@db-ux/core-foundations 4.5.4-mcp-e4cd7e6 → 4.5.4-mcp-server-6cda8b3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/build/mcp/index.js +1018 -73
  2. package/package.json +1 -1
@@ -2980,7 +2980,7 @@ var require_compile = __commonJS({
2980
2980
  const schOrFunc = root.refs[ref];
2981
2981
  if (schOrFunc)
2982
2982
  return schOrFunc;
2983
- let _sch = resolve3.call(this, root, ref);
2983
+ let _sch = resolve2.call(this, root, ref);
2984
2984
  if (_sch === void 0) {
2985
2985
  const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
2986
2986
  const { schemaId } = this.opts;
@@ -3007,7 +3007,7 @@ var require_compile = __commonJS({
3007
3007
  function sameSchemaEnv(s1, s2) {
3008
3008
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3009
3009
  }
3010
- function resolve3(root, ref) {
3010
+ function resolve2(root, ref) {
3011
3011
  let sch;
3012
3012
  while (typeof (sch = this.refs[ref]) == "string")
3013
3013
  ref = sch;
@@ -3582,7 +3582,7 @@ var require_fast_uri = __commonJS({
3582
3582
  }
3583
3583
  return uri;
3584
3584
  }
3585
- function resolve3(baseURI, relativeURI, options) {
3585
+ function resolve2(baseURI, relativeURI, options) {
3586
3586
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3587
3587
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3588
3588
  schemelessOptions.skipEscape = true;
@@ -3809,7 +3809,7 @@ var require_fast_uri = __commonJS({
3809
3809
  var fastUri = {
3810
3810
  SCHEMES,
3811
3811
  normalize,
3812
- resolve: resolve3,
3812
+ resolve: resolve2,
3813
3813
  resolveComponent,
3814
3814
  equal,
3815
3815
  serialize,
@@ -13164,12 +13164,12 @@ var StdioServerTransport = class {
13164
13164
  this.onclose?.();
13165
13165
  }
13166
13166
  send(message) {
13167
- return new Promise((resolve3) => {
13167
+ return new Promise((resolve2) => {
13168
13168
  const json = serializeMessage(message);
13169
13169
  if (this._stdout.write(json)) {
13170
- resolve3();
13170
+ resolve2();
13171
13171
  } else {
13172
- this._stdout.once("drain", resolve3);
13172
+ this._stdout.once("drain", resolve2);
13173
13173
  }
13174
13174
  });
13175
13175
  }
@@ -19506,7 +19506,7 @@ var Protocol = class {
19506
19506
  return;
19507
19507
  }
19508
19508
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
19509
- await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
19509
+ await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
19510
19510
  options?.signal?.throwIfAborted();
19511
19511
  }
19512
19512
  } catch (error2) {
@@ -19523,7 +19523,7 @@ var Protocol = class {
19523
19523
  */
19524
19524
  request(request, resultSchema, options) {
19525
19525
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
19526
- return new Promise((resolve3, reject) => {
19526
+ return new Promise((resolve2, reject) => {
19527
19527
  const earlyReject = (error2) => {
19528
19528
  reject(error2);
19529
19529
  };
@@ -19601,7 +19601,7 @@ var Protocol = class {
19601
19601
  if (!parseResult.success) {
19602
19602
  reject(parseResult.error);
19603
19603
  } else {
19604
- resolve3(parseResult.data);
19604
+ resolve2(parseResult.data);
19605
19605
  }
19606
19606
  } catch (error2) {
19607
19607
  reject(error2);
@@ -19862,12 +19862,12 @@ var Protocol = class {
19862
19862
  }
19863
19863
  } catch {
19864
19864
  }
19865
- return new Promise((resolve3, reject) => {
19865
+ return new Promise((resolve2, reject) => {
19866
19866
  if (signal.aborted) {
19867
19867
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
19868
19868
  return;
19869
19869
  }
19870
- const timeoutId = setTimeout(resolve3, interval);
19870
+ const timeoutId = setTimeout(resolve2, interval);
19871
19871
  signal.addEventListener("abort", () => {
19872
19872
  clearTimeout(timeoutId);
19873
19873
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -20967,7 +20967,7 @@ var McpServer = class {
20967
20967
  let task = createTaskResult.task;
20968
20968
  const pollInterval = task.pollInterval ?? 5e3;
20969
20969
  while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
20970
- await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
20970
+ await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
20971
20971
  const updatedTask = await extra.taskStore.getTask(taskId);
20972
20972
  if (!updatedTask) {
20973
20973
  throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
@@ -21555,7 +21555,8 @@ var package_default = {
21555
21555
  ],
21556
21556
  scripts: {
21557
21557
  build: "node esbuild.js",
21558
- dev: "tsx src/index.ts",
21558
+ "build-manifest": "npx tsx src/build-manifest.ts",
21559
+ dev: "npm run build-manifest && tsx src/index.ts",
21559
21560
  test: "vitest run",
21560
21561
  "test:unit": "vitest run src/__tests__/integration.test.ts src/__tests__/buildManifest.test.ts",
21561
21562
  "test:e2e": "vitest run src/__tests__/e2e.test.ts"
@@ -21599,18 +21600,16 @@ function registerLifecycleHandlers() {
21599
21600
  }
21600
21601
 
21601
21602
  // ../mcp-server/src/tools/components.ts
21602
- import { existsSync as existsSync3 } from "node:fs";
21603
- import { readFile as readFile2, readdir } from "node:fs/promises";
21604
- import { join as join3 } from "node:path";
21603
+ import { existsSync as existsSync2 } from "node:fs";
21604
+ import { readFile, readdir } from "node:fs/promises";
21605
+ import { join as join2 } from "node:path";
21605
21606
 
21606
21607
  // ../mcp-server/src/utils/path.ts
21607
21608
  import { existsSync } from "node:fs";
21608
21609
  import { join, resolve, sep } from "node:path";
21609
21610
  var SERVER_DIR = import.meta.dirname;
21610
21611
  var REPO_ROOT = resolve(SERVER_DIR, "../../../..");
21611
- var IS_MONOREPO = existsSync(
21612
- join(REPO_ROOT, "packages/components/src/components")
21613
- );
21612
+ var IS_MONOREPO = process.env["FORCE_MANIFEST"] !== "1" && existsSync(join(REPO_ROOT, "packages/components/src/components"));
21614
21613
  var COMPONENTS_DIR = join(
21615
21614
  REPO_ROOT,
21616
21615
  "packages/components/src/components"
@@ -21643,26 +21642,972 @@ function resolveSafePath(baseDir, userPath) {
21643
21642
  return absoluteRequested;
21644
21643
  }
21645
21644
 
21645
+ // ../mcp-server/src/manifest.json
21646
+ var manifest_default = { icons: ["arrow_down", "arrow_left", "arrow_right", "arrow_up", "arrow_up_right", "brand", "calendar", "chat", "check", "check_circle", "chevron_down", "chevron_left", "chevron_right", "chevron_up", "circle", "circle_small", "circular_arrows", "clock", "copy", "cross", "cross_circle", "double_chevron_down", "double_chevron_left", "double_chevron_right", "double_chevron_up", "exclamation_mark_circle", "exclamation_mark_triangle", "eye", "eye_disabled", "house", "information_circle", "magnifying_glass", "menu", "minus", "moon", "plus", "resize_handle_corner", "sun", "x_placeholder"], components: { accordion: { props: `import { GlobalProps, InitializedState } from '../../shared/model';
21647
+ import { DBAccordionItemDefaultProps } from '../accordion-item/model';
21648
+
21649
+ export const AccordionVariantList = ['divider', 'card'] as const;
21650
+ export type AccordionVariantType = (typeof AccordionVariantList)[number];
21651
+
21652
+ export const AccordionBehaviorList = ['multiple', 'single'] as const;
21653
+ export type AccordionBehaviorType = (typeof AccordionBehaviorList)[number];
21654
+
21655
+ export type DBAccordionDefaultProps = {
21656
+ /**
21657
+ * To allow multiple items open at the same time or only 1 item
21658
+ */
21659
+ behavior?: AccordionBehaviorType;
21660
+ /**
21661
+ * The index of items which should be open when loading the accordion
21662
+ */
21663
+ initOpenIndex?: number[];
21664
+
21665
+ /**
21666
+ * Alternative to pass in a simple representation of accordion items
21667
+ */
21668
+ items?: DBAccordionItemDefaultProps[] | string;
21669
+
21670
+ /**
21671
+ * Set details name for exclusive accordions, see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#name
21672
+ */
21673
+ name?: string;
21674
+
21675
+ /**
21676
+ * Informs about the changes in the internal state, which item is open
21677
+ */
21678
+ onChange?: (openAccordionItemIds: string[]) => void;
21679
+
21680
+ /**
21681
+ * Defines the display of the accordion and the items:
21682
+ * "divider": with a dividing line between the items
21683
+ * "card": w/o dividing line, but items are shown in the card variant
21684
+ */
21685
+ variant?: AccordionVariantType;
21686
+ };
21687
+
21688
+ export type DBAccordionProps = DBAccordionDefaultProps & GlobalProps;
21689
+
21690
+ export type DBAccordionDefaultState = {
21691
+ _initOpenIndexDone: boolean;
21692
+ _name?: string;
21693
+ convertItems: () => DBAccordionItemDefaultProps[];
21694
+ };
21695
+
21696
+ export type DBAccordionState = DBAccordionDefaultState & InitializedState;
21697
+ `, examples: ["Density", "Variant", "Behavior"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBAccordion</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-accordion">Test</div>\n </body>\n</html>\n' } } }, "accordion-item": { props: "import {\n GlobalProps,\n InitializedState,\n NameProps,\n NameState,\n TextProps,\n ToggleEventProps,\n ToggleEventState\n} from '../../shared/model';\n\nexport type DBAccordionItemDefaultProps = {\n /**\n * Initial state for the accordion item\n */\n defaultOpen?: boolean;\n /**\n * The disabled attribute can be set to keep a user from clicking on the element.\n */\n disabled?: boolean | string;\n /**\n * Title of the accordion-item as slot\n */\n headline?: any;\n /**\n * Title of the accordion-item as plain text\n */\n headlinePlain?: string;\n} & TextProps;\n\nexport type DBAccordionItemProps = DBAccordionItemDefaultProps &\n GlobalProps &\n ToggleEventProps &\n NameProps;\n\nexport type DBAccordionItemDefaultState = {\n _open?: boolean;\n};\n\nexport type DBAccordionItemState = DBAccordionItemDefaultState &\n ToggleEventState<HTMLElement> &\n InitializedState &\n NameState;\n", examples: ["Density", "Disabled", "Open"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBAccordionItem</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <!-- HTML only component -->\n <details class="db-accordion-item">\n <summary>DB Accordion Item</summary>\n <div class="db-accordion-content">Here is the content</div>\n </details>\n </body>\n</html>\n' } } }, badge: { props: "import {\n EmphasisProps,\n GlobalProps,\n GlobalState,\n InitializedState,\n SemanticProps,\n SizeProps,\n TextProps,\n WrapProps\n} from '../../shared/model';\n\nexport const BadgePlacementList = [\n 'inline',\n 'corner-top-left',\n 'corner-top-right',\n 'corner-center-left',\n 'corner-center-right',\n 'corner-bottom-left',\n 'corner-bottom-right'\n] as const;\nexport type BadgePlacementType = (typeof BadgePlacementList)[number];\n\nexport type DBBadgeDefaultProps = {\n /**\n * The `placement` attributes `corner-*` values change the position to absolute and adds a transform based on the placement.\n */\n placement?: BadgePlacementType;\n\n /**\n * Describes the badge for a11y if you use placement attribute with `corner-*`\n */\n label?: string;\n};\n\nexport type DBBadgeProps = DBBadgeDefaultProps &\n GlobalProps &\n SemanticProps &\n SizeProps &\n EmphasisProps &\n TextProps &\n WrapProps;\n\nexport type DBBadgeDefaultState = {};\n\nexport type DBBadgeState = DBBadgeDefaultState & GlobalState & InitializedState;\n", examples: ["Density", "Emphasis", "Semantic", "Size", "Content", "Placement", "Examples"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBBadge</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <span class="db-badge">test </span>\n </body>\n</html>\n' } } }, brand: { props: "import {\n GlobalProps,\n GlobalState,\n IconProps,\n ShowIconProps,\n TextProps\n} from '../../shared/model';\n\nexport type DBBrandDefaultProps = {\n /**\n * @deprecated: Disable the default logo svg to pass in a custom `img`\n */\n hideLogo?: boolean;\n};\n\nexport type DBBrandProps = DBBrandDefaultProps &\n GlobalProps &\n IconProps &\n ShowIconProps &\n TextProps;\n\nexport type DBBrandDefaultState = {};\n\nexport type DBBrandState = DBBrandDefaultState & GlobalState;\n", examples: ["Density", "Variants"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBBrand</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-brand">\n <img\n src="/assets/images/db_logo.svg"\n alt="DBBrand"\n width="34"\n height="24"\n />Brand\n </div>\n </body>\n</html>\n' } } }, button: { props: "import {\n ClickEventProps,\n GlobalProps,\n GlobalState,\n IconLeadingProps,\n IconProps,\n IconTrailingProps,\n NoTextProps,\n ShowIconLeadingProps,\n ShowIconProps,\n ShowIconTrailingProps,\n SizeProps,\n TextProps,\n WidthProps,\n WrapProps\n} from '../../shared/model';\n\nexport const ButtonVariantList = [\n 'outlined',\n 'brand',\n 'filled',\n 'ghost'\n] as const;\nexport type ButtonVariantType = (typeof ButtonVariantList)[number];\n\nexport const ButtonTypeList = ['button', 'reset', 'submit'] as const;\nexport type ButtonTypeType = (typeof ButtonTypeList)[number];\n\nexport type DBButtonSharedProps = {\n /**\n * Variant of the button. Only use one primary button as a CTA on a page; otherwise, use one of the adaptive buttons.\n */\n variant?: ButtonVariantType | string;\n};\n\nexport type DBButtonDefaultProps = {\n /**\n * The disabled attribute can be set to [keep a user from clicking on the button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled).\n */\n disabled?: boolean | string;\n /**\n * Associates the control with a form element\n */\n form?: string;\n\n /**\n * The name attribute specifies a [name attributes value](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#name) for the button.\n */\n name?: string;\n\n /**\n * The type attribute specifies the [type of button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type).\n */\n type?: ButtonTypeType;\n\n /**\n * The value attribute specifies an initial [value for the button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#value).\n */\n value?: string;\n};\n\nexport type DBButtonProps = DBButtonDefaultProps &\n DBButtonSharedProps &\n GlobalProps &\n ClickEventProps<HTMLButtonElement> &\n IconProps &\n WidthProps &\n SizeProps &\n ShowIconProps &\n TextProps &\n ShowIconLeadingProps &\n ShowIconTrailingProps &\n IconLeadingProps &\n IconTrailingProps &\n WrapProps &\n NoTextProps;\n\nexport type DBButtonDefaultState = {\n getButtonType: () => ButtonTypeType;\n};\n\nexport type DBButtonState = DBButtonDefaultState & GlobalState;\n", examples: ["Density", "Variant", "Disabled", "Size", "Show Icon Leading", "Show Icon Trailing", "No Text", "Width", "Multi-line Text With Line Breaks"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBButton</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <button class="db-button" data-variant="brand" type="button">\n Button\n </button>\n <button\n class="db-button"\n data-icon="x_placeholder"\n data-variant="brand"\n type="button"\n >\n data-icon="x_placeholder"\n </button>\n <button\n class="db-button"\n data-icon="none"\n data-variant="brand"\n type="button"\n >\n data-icon="none"\n </button>\n </body>\n</html>\n' } } }, card: { props: "import {\n ClickEventProps,\n ClickEventState,\n GlobalProps,\n GlobalState,\n SpacingProps\n} from '../../shared/model';\n\nexport const CardBehaviorList = ['static', 'interactive'] as const;\nexport type CardBehaviorType = (typeof CardBehaviorList)[number];\n\nexport const CardElevationLevelList = ['1', '2', '3'] as const;\nexport type CardElevationLevelType = (typeof CardElevationLevelList)[number];\n\nexport type DBCardDefaultProps = {\n /**\n * Makes the card interactive\n */\n behavior?: CardBehaviorType;\n\n /**\n * Changes the elevation of the card which is equal to `basic-background-level`\n */\n elevationLevel?: CardElevationLevelType;\n};\n\nexport type DBCardProps = DBCardDefaultProps &\n GlobalProps &\n ClickEventProps<HTMLElement> &\n SpacingProps;\n\nexport type DBCardDefaultState = {};\n\nexport type DBCardState = DBCardDefaultState &\n GlobalState &\n ClickEventState<HTMLElement>;\n", examples: ["Density", "Elevation Level", "Spacing", "Behavior", "Example"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBCard</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-card">Card content</div>\n </body>\n</html>\n' } } }, checkbox: { props: "import {\n ChangeEventProps,\n ChangeEventState,\n FocusEventProps,\n FocusEventState,\n FormCheckProps,\n FormMessageProps,\n FormProps,\n FormState,\n FromValidState,\n GlobalProps,\n GlobalState,\n InitializedState,\n SizeProps\n} from '../../shared/model';\n\nexport type DBCheckboxDefaultProps = {\n /**\n * Define an [indeterminate](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#indeterminate) state of a checkbox\n */\n indeterminate?: boolean | string;\n};\n\nexport type DBCheckboxProps = DBCheckboxDefaultProps &\n GlobalProps &\n ChangeEventProps<HTMLInputElement> &\n FocusEventProps<HTMLInputElement> &\n FormProps &\n FormCheckProps &\n FormMessageProps &\n SizeProps;\n\nexport type DBCheckboxDefaultState = {};\n\nexport type DBCheckboxState = DBCheckboxDefaultState &\n GlobalState &\n ChangeEventState<HTMLInputElement> &\n FocusEventState<HTMLInputElement> &\n FormState &\n InitializedState &\n FromValidState;\n", examples: ["Density", "Disabled", "Checked", "Indeterminate", "Validation", "Size", "Required", "Show Label", "Example", "Show Required Asterisk"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBCheckbox</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <input\n type="checkbox"\n class="db-checkbox"\n id="checkbox-element"\n name="States"\n />\n <label for="checkbox-element">Label</label>\n </body>\n</html>\n' } } }, "custom-button": { props: "import {\n GlobalProps,\n GlobalState,\n IconLeadingProps,\n IconProps,\n IconTrailingProps,\n NoTextProps,\n ShowIconLeadingProps,\n ShowIconProps,\n ShowIconTrailingProps,\n SizeProps,\n WidthProps,\n WrapProps\n} from '../../shared/model';\nimport { DBButtonSharedProps } from '../button/model';\n\nexport type DBCustomButtonDefaultProps = {};\n\nexport type DBCustomButtonProps = DBCustomButtonDefaultProps &\n DBButtonSharedProps &\n GlobalProps &\n IconProps &\n WidthProps &\n SizeProps &\n ShowIconProps &\n ShowIconLeadingProps &\n ShowIconTrailingProps &\n IconLeadingProps &\n IconTrailingProps &\n NoTextProps &\n WrapProps;\n\nexport type DBCustomButtonDefaultState = {};\n\nexport type DBCustomButtonState = DBCustomButtonDefaultState & GlobalState;\n", examples: ["Density", "Variant", "Disabled", "Size", "Show Icon Leading", "Show Icon Trailing", "No Text", "Width", "Multi-line Text With Line Breaks", "Checkbox Example"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBCustomButton</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-custom-button"><button type="test">Test</button></div>\n </body>\n</html>\n' } } }, "custom-select": { props: `import {
21698
+ BaseFormProps,
21699
+ ClickEvent,
21700
+ CloseEventState,
21701
+ CustomFormProps,
21702
+ DocumentScrollState,
21703
+ FormMessageProps,
21704
+ FormState,
21705
+ FromValidState,
21706
+ GeneralEvent,
21707
+ GlobalProps,
21708
+ GlobalState,
21709
+ IconProps,
21710
+ InputEvent,
21711
+ InteractionEvent,
21712
+ PlacementVerticalType,
21713
+ RequiredProps,
21714
+ ShowIconProps,
21715
+ ShowLabelProps,
21716
+ ValidationType,
21717
+ WidthType
21718
+ } from '../../shared/model';
21719
+ import { CustomSelectDropdownWidthType } from '../custom-select-dropdown/model';
21720
+ import { DBCustomSelectFormFieldDefaultProps } from '../custom-select-form-field/model';
21721
+ import { DBCustomSelectListItemExtraProps } from '../custom-select-list-item/model';
21722
+
21723
+ export type CustomSelectOptionType = {
21724
+ /**
21725
+ * Disables this option
21726
+ */
21727
+ disabled?: boolean;
21728
+
21729
+ /**
21730
+ * Identifier for option
21731
+ */
21732
+ id?: string;
21733
+
21734
+ /**
21735
+ * If the value is different from the label you want to show to the user.
21736
+ */
21737
+ label?: string;
21738
+
21739
+ /**
21740
+ * The value for the option
21741
+ */
21742
+ value?: string;
21743
+ } & DBCustomSelectListItemExtraProps;
21744
+
21745
+ export const SelectedTypeList = ['amount', 'text', 'tag'] as const;
21746
+ export type SelectedTypeType = (typeof SelectedTypeList)[number];
21747
+
21748
+ export type DBCustomSelectEvents = {
21749
+ /**
21750
+ * Optional: if select-type="amount" when amount changes
21751
+ * @param amount The amount of selected checkboxes
21752
+ */
21753
+ onAmountChange?: (amount: number) => void;
21754
+
21755
+ /**
21756
+ * Optional: if select-type="amount" when amount changes
21757
+ * @param amount The amount of selected checkboxes
21758
+ */
21759
+ amountChange?: (amount: number) => void;
21760
+ /**
21761
+ * Triggers after some option was clicked in dropdown
21762
+ * @param values the changed values
21763
+ */
21764
+ onOptionSelected?: (values: string[]) => void;
21765
+ /**
21766
+ * Triggers after some option was clicked in dropdown
21767
+ * @param values the changed values
21768
+ */
21769
+ optionSelected?: (values: string[]) => void;
21770
+
21771
+ /**
21772
+ * Informs the user when dropdown was toggled.
21773
+ */
21774
+ onDropdownToggle?: (event: GeneralEvent<HTMLDetailsElement>) => void;
21775
+ /**
21776
+ * Informs the user when dropdown was toggled.
21777
+ */
21778
+ dropdownToggle?: (event: GeneralEvent<HTMLDetailsElement>) => void;
21779
+
21780
+ /**
21781
+ * Informs the user when a search was performed.
21782
+ */
21783
+ onSearch?: (event: InputEvent<HTMLInputElement>) => void;
21784
+ /**
21785
+ * Informs the user when a search was performed.
21786
+ */
21787
+ search?: (event: InputEvent<HTMLInputElement>) => void;
21788
+ };
21789
+
21790
+ export type DBCustomSelectDefaultProps = {
21791
+ /**
21792
+ * Optional: if select-type="amount" change the shown text
21793
+ */
21794
+ amountText?: string;
21795
+ /**
21796
+ * Overwrite the default aria-label (props.label) for the custom-select-list
21797
+ */
21798
+ listLabel?: string;
21799
+
21800
+ /**
21801
+ * Label for the clear selection button
21802
+ */
21803
+ clearSelectionText?: string;
21804
+
21805
+ /**
21806
+ * Changes the behavior of the dropdown with.
21807
+ * Default: fixed 328px
21808
+ * Auto: Based on the size of the form-field
21809
+ */
21810
+ dropdownWidth?: CustomSelectDropdownWidthType | string;
21811
+
21812
+ /**
21813
+ * Width of the component. Auto width based on children size, full width based on parent elements width.
21814
+ */
21815
+ formFieldWidth?: WidthType | string;
21816
+
21817
+ /**
21818
+ * Dropdown - hint if data has to be loaded
21819
+ */
21820
+ loadingText?: string;
21821
+
21822
+ /**
21823
+ * Change the button text for mobile close
21824
+ */
21825
+ mobileCloseButtonText?: string;
21826
+
21827
+ /**
21828
+ * Enables CustomSelect
21829
+ */
21830
+
21831
+ multiple?: boolean | string;
21832
+ /**
21833
+ * Dropdown - hint if there are no options
21834
+ */
21835
+ noResultsText?: string;
21836
+ /**
21837
+ * Programmatically open the dropdown. May differ if you don't use onDropdownToggle.
21838
+ */
21839
+ open?: boolean;
21840
+
21841
+ /**
21842
+ * You should pass in the options as an array.
21843
+ */
21844
+ options?: CustomSelectOptionType[];
21845
+
21846
+ /**
21847
+ * The \`placement\` attributes values change the position to absolute and adds a transform based on the placement.
21848
+ */
21849
+ placement?: PlacementVerticalType;
21850
+
21851
+ /**
21852
+ * Optional: if you use selectedType=tag and options, you need to set the removeTagsTexts for screen reader users
21853
+ */
21854
+ removeTagsTexts?: string[];
21855
+
21856
+ /**
21857
+ * Optional: Change the filter function for the search input
21858
+ */
21859
+ searchFilter?: (
21860
+ option: CustomSelectOptionType,
21861
+ filterText: string
21862
+ ) => boolean;
21863
+
21864
+ /**
21865
+ * Search label
21866
+ */
21867
+ searchLabel?: string;
21868
+
21869
+ /**
21870
+ * Search placeholder
21871
+ */
21872
+ searchPlaceholder?: string;
21873
+
21874
+ /**
21875
+ * Optional: Prefill the value of the search input
21876
+ */
21877
+ searchValue?: string;
21878
+
21879
+ /**
21880
+ * Select all checkbox label
21881
+ */
21882
+ selectAllLabel?: string;
21883
+
21884
+ /**
21885
+ * Optional: If you want to show a custom label for the selected values.
21886
+ * You need to define the empty state as well based on selected options.
21887
+ */
21888
+ selectedLabels?: string;
21889
+
21890
+ /**
21891
+ * Optional: Prefix text announced by screen readers before the selection
21892
+ * (e.g. "Selected").
21893
+ */
21894
+ selectedPrefix?: string;
21895
+
21896
+ /**
21897
+ * Change the selected type for values shown in multi select
21898
+ */
21899
+ selectedType?: SelectedTypeType;
21900
+
21901
+ /**
21902
+ * Show clear selection button (default:true). Hide it if you have very small inputs e.g. in tables.
21903
+ */
21904
+ showClearSelection?: boolean;
21905
+
21906
+ /**
21907
+ * Dropdown - enable loading infotext and spinner
21908
+ */
21909
+ showLoading?: boolean;
21910
+
21911
+ /**
21912
+ * Dropdown - enable no options infotext
21913
+ */
21914
+ showNoResults?: boolean;
21915
+
21916
+ /**
21917
+ * Forces search in header.
21918
+ */
21919
+ showSearch?: boolean;
21920
+ /**
21921
+ * Forces select all checkbox (only for multiple).
21922
+ */
21923
+ showSelectAll?: boolean;
21924
+
21925
+ /**
21926
+ * Optional: If you want to show a custom label based on the selected options.
21927
+ */
21928
+ transformSelectedLabels?: (
21929
+ selectedOptions?: CustomSelectOptionType[]
21930
+ ) => string;
21931
+
21932
+ /**
21933
+ * Initial value for multi select
21934
+ */
21935
+ values?: string[];
21936
+ };
21937
+
21938
+ export type DBCustomSelectProps = GlobalProps &
21939
+ CustomFormProps &
21940
+ BaseFormProps &
21941
+ RequiredProps &
21942
+ FormMessageProps &
21943
+ DBCustomSelectDefaultProps &
21944
+ DBCustomSelectEvents &
21945
+ DBCustomSelectFormFieldDefaultProps &
21946
+ IconProps &
21947
+ ShowIconProps &
21948
+ ShowLabelProps;
21949
+
21950
+ export type DBCustomSelectDefaultState = {
21951
+ _validity?: ValidationType;
21952
+ _values?: string[];
21953
+ _options?: CustomSelectOptionType[];
21954
+ _selectedOptions?: CustomSelectOptionType[];
21955
+ _hasNoOptions: boolean;
21956
+ _selectId?: string;
21957
+ _labelId?: string;
21958
+ _summaryId?: string;
21959
+ _placeholderId?: string;
21960
+ _selectedLabels?: string;
21961
+ _selectedLabelsId?: string;
21962
+ _infoTextId?: string;
21963
+ _internalChangeTimestamp: number;
21964
+ _documentClickListenerCallbackId?: string;
21965
+ _searchValue?: string;
21966
+ _userInteraction?: boolean;
21967
+ getNativeSelectValue: () => string;
21968
+ getOptionLabel: (option: CustomSelectOptionType) => string;
21969
+ getOptionChecked: (value?: string) => boolean;
21970
+ getTagRemoveLabel: (option: CustomSelectOptionType) => string;
21971
+ selectAllEnabled: boolean;
21972
+ searchEnabled: boolean;
21973
+ amountOptions: number;
21974
+ setDescById: (descId?: string) => void;
21975
+ handleTagRemove: (
21976
+ option: CustomSelectOptionType,
21977
+ event?: ClickEvent<HTMLButtonElement> | void
21978
+ ) => void;
21979
+ handleSummaryFocus: () => void;
21980
+ handleSelect: (value?: string) => void;
21981
+ handleSelectAll: (event: any) => void;
21982
+ handleClearAll: (event: any) => void;
21983
+ handleDropdownToggle: (event: any) => void;
21984
+ handleDocumentClose: (event: any) => void;
21985
+ handleOpenByKeyboardFocus: () => void;
21986
+ handleFocusFirstDropdownCheckbox: (activeElement?: Element) => void;
21987
+ handleKeyboardPress: (event: any) => void;
21988
+ handleArrowDownUp: (event: any) => void;
21989
+ handleSearch: (event: any) => void;
21990
+ handleOptionSelected: (_values: string[]) => void;
21991
+ getSelectAllLabel: () => string;
21992
+ selectAllChecked: boolean;
21993
+ selectAllIndeterminate: boolean;
21994
+ handleAutoPlacement: () => void;
21995
+ };
21996
+
21997
+ export type DBCustomSelectState = DBCustomSelectDefaultState &
21998
+ GlobalState &
21999
+ FormState &
22000
+ FromValidState &
22001
+ CloseEventState<InteractionEvent<HTMLDetailsElement>> &
22002
+ DocumentScrollState;
22003
+ `, examples: ["Density", "Multiple", "Variant", "Show Label", "Show Message", "Show Icon", "Validation", "Required", "Show Required Asterisk", "Disabled", "Form Field Width", "Dropdown Width", "Placement", "Selected type", "Show No Result", "Show Loading", "Show Search", "Show Select All", "Show Clear Selection", "Examples Single", "Examples Multiple", "Example tags", "Example: Other configuration", "Examples Floating label"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBCustomSelect</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-custom-select">Test</div>\n </body>\n</html>\n' } } }, "custom-select-dropdown": { props: "import { GlobalProps, GlobalState } from '../../shared/model';\n\nexport const CustomSelectDropdownWidthList = ['fixed', 'auto', 'full'] as const;\nexport type CustomSelectDropdownWidthType =\n (typeof CustomSelectDropdownWidthList)[number];\n\nexport type DBCustomSelectDropdownDefaultProps = {\n /**\n * Changes the behavior of the dropdown with.\n * Default: fixed 328px\n * Full: Based on the size of the form-field\n * Auto: Based on the size of the largest list item\n */\n width?: CustomSelectDropdownWidthType | string;\n};\n\nexport type DBCustomSelectDropdownProps = DBCustomSelectDropdownDefaultProps &\n GlobalProps;\n\nexport type DBCustomSelectDropdownDefaultState = {};\n\nexport type DBCustomSelectDropdownState = DBCustomSelectDropdownDefaultState &\n GlobalState;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBCustomSelectDropdown</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-custom-select-dropdown">Test</div>\n </body>\n</html>\n' } } }, "custom-select-form-field": { props: "import { GlobalProps, GlobalState } from '../../shared/model';\n\nexport type DBCustomSelectFormFieldDefaultProps = {};\n\nexport type DBCustomSelectFormFieldProps = DBCustomSelectFormFieldDefaultProps &\n GlobalProps;\n\nexport type DBCustomSelectFormFieldDefaultState = {};\n\nexport type DBCustomSelectFormFieldState = DBCustomSelectFormFieldDefaultState &\n GlobalState;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBCustomSelectFormField</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-custom-select-form-field">Test</div>\n </body>\n</html>\n' } } }, "custom-select-list": { props: "import { GlobalProps, GlobalState } from '../../shared/model';\n\nexport type DBCustomSelectListDefaultProps = {\n label?: string;\n multiple?: boolean;\n};\n\nexport type DBCustomSelectListProps = DBCustomSelectListDefaultProps &\n GlobalProps;\n\nexport type DBCustomSelectListDefaultState = {};\n\nexport type DBCustomSelectListState = DBCustomSelectListDefaultState &\n GlobalState;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: {} } }, "custom-select-list-item": { props: "import {\n BaseFormProps,\n ChangeEventProps,\n ChangeEventState,\n FormCheckProps,\n GlobalProps,\n IconProps,\n ShowIconProps,\n ValueProps\n} from '../../shared/model';\n\nexport const CustomSelectListItemTypeList = ['checkbox', 'radio'] as const;\nexport type CustomSelectListItemTypeType =\n (typeof CustomSelectListItemTypeList)[number];\n\nexport type DBCustomSelectListItemExtraProps = {\n /**\n * If the item is a group title (only text)\n */\n isGroupTitle?: boolean;\n /**\n * Show a divider on the bottom of the list item for visual grouping (don't use it on every item)\n */\n showDivider?: boolean;\n} & IconProps &\n ShowIconProps;\n\nexport type DBCustomSelectListItemDefaultProps = {\n /**\n * Set the title of a group of items - disables radio/checkbox behavior\n */\n groupTitle?: string;\n /**\n * Change the behavior of the item single(radio) or multiple(checkbox)\n */\n type?: CustomSelectListItemTypeType;\n};\n\nexport type DBCustomSelectListItemProps = DBCustomSelectListItemDefaultProps &\n GlobalProps &\n BaseFormProps &\n ValueProps &\n FormCheckProps &\n ChangeEventProps<HTMLInputElement> &\n DBCustomSelectListItemExtraProps;\n\nexport type DBCustomSelectListItemDefaultState = {\n getIconTrailing: () => string | undefined;\n hasDivider?: boolean;\n};\n\nexport type DBCustomSelectListItemState = DBCustomSelectListItemDefaultState &\n ChangeEventState<HTMLInputElement>;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: {} } }, divider: { props: "import {\n EmphasisProps,\n GlobalProps,\n GlobalState,\n MarginProps,\n WidthProps\n} from '../../shared/model';\n\nexport const DividerMarginList = ['none', '_'] as const;\nexport type DividerMarginType = (typeof DividerMarginList)[number];\n\nexport const DividerVariantList = ['horizontal', 'vertical'] as const;\nexport type DividerVariantType = (typeof DividerVariantList)[number];\n\nexport type DBDividerDefaultProps = {\n /**\n * Removes the margin of the divider.\n */\n margin?: DividerMarginType;\n /**\n * Changes the orientation of the divider.\n */\n variant?: DividerVariantType;\n};\n\nexport type DBDividerProps = DBDividerDefaultProps &\n GlobalProps &\n EmphasisProps &\n MarginProps &\n WidthProps;\n\nexport type DBDividerDefaultState = {};\n\nexport type DBDividerState = DBDividerDefaultState & GlobalState;\n", examples: ["Density", "Variant", "Emphasis"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBDivider</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-divider"></div>\n </body>\n</html>\n' } } }, drawer: { props: "import {\n ClickEvent,\n CloseEventProps,\n CloseEventState,\n GeneralKeyboardEvent,\n GlobalProps,\n GlobalState,\n InitializedState,\n InnerCloseButtonProps,\n SpacingProps,\n WidthProps\n} from '../../shared/model';\n\nexport const DrawerBackdropList = [\n 'none',\n 'strong',\n 'weak',\n 'invisible'\n] as const;\nexport type DrawerBackdropType = (typeof DrawerBackdropList)[number];\n\nexport const DrawerDirectionList = ['left', 'right', 'up', 'down'] as const;\nexport type DrawerDirectionType = (typeof DrawerDirectionList)[number];\n\nexport const DrawerVariantList = ['modal', 'inside'] as const;\nexport type DrawerVariantType = (typeof DrawerVariantList)[number];\n\nexport const DrawerPositionList = ['fixed', 'absolute'] as const;\nexport type DrawerPositionType = (typeof DrawerPositionList)[number];\n\nexport type DBDrawerDefaultProps = {\n /**\n * The backdrop attribute changes the opacity of the backdrop.\n * The backdrop 'none' will use `dialog.show()` instead of `dialog.showModal()`\n */\n backdrop?: DrawerBackdropType;\n /**\n * The direction attribute changes the position & animation of the drawer.\n * E.g. \"left\" slides from left screen border to the right.\n */\n direction?: DrawerDirectionType;\n\n /**\n * Slot for changing the header of the drawer.\n */\n drawerHeader?: any;\n\n /**\n * The open attribute opens or closes the drawer based on the state.\n */\n open?: boolean | string;\n /**\n * The rounded attribute changes the border radius of the corners on the \"end\" of the drawer.\n * The \"end\" depends on which direction you use.\n */\n rounded?: boolean | string;\n /**\n * Set the variant modal|inside. Defaults to modal.\n */\n variant?: DrawerVariantType;\n /**\n * The position attribute changes the css-position (fixed or absolute) of the drawer.\n *\n * - `fixed` (default): Renders with `showModal()`, creating a true modal with a focus trap.\n * - `absolute`: Renders with `show()`, acting as a simple overlay **without** a focus trap.\n */\n position?: DrawerPositionType;\n};\n\nexport type DBDrawerProps = DBDrawerDefaultProps &\n GlobalProps &\n CloseEventProps<\n | ClickEvent<HTMLButtonElement | HTMLDialogElement>\n | GeneralKeyboardEvent<HTMLDialogElement>\n > &\n InnerCloseButtonProps &\n WidthProps &\n SpacingProps;\n\nexport type DBDrawerDefaultState = {\n handleDialogOpen: () => void;\n};\n\nexport type DBDrawerState = DBDrawerDefaultState &\n GlobalState &\n CloseEventState<\n | ClickEvent<HTMLButtonElement | HTMLDialogElement>\n | GeneralKeyboardEvent<HTMLDialogElement>\n > &\n InitializedState;\n", examples: ["Density", "Size", "Rounded", "Spacing", "Backdrop", "Direction", "Example"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBDrawer</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <dialog class="db-drawer" data-backdrop="true" open>\n <article class="db-drawer-container">\n <header class="db-drawer-header">\n <button\n class="db-button button-close-drawer is-icon-text-replace"\n data-icon="cross"\n data-variant="ghost"\n >\n Close Button\n </button>\n </header>\n <div class="db-drawer-content">My Drawer content</div>\n </article>\n </dialog>\n </body>\n</html>\n' } } }, header: { props: "import {\n ContainerWidthProps,\n GlobalProps,\n GlobalState,\n InitializedState,\n InnerCloseButtonProps,\n NavigationBehaviorState,\n ToggleEventProps,\n ToggleEventState\n} from '../../shared/model';\n\nexport type DBHeaderDefaultProps = {\n /**\n * Slot to pass in the DBBrand component\n */\n brand?: any;\n /**\n * Slot to pass in a meta navigation.\n * - Desktop: Above the regular header\n * - Mobile: Inside the drawer\n */\n metaNavigation?: any;\n /**\n * Slot to pass one or more elements like DBButton (e.g. search) as primary action.\n * - Desktop: Shown next to the main-navigation\n * - Mobile: Shown next to the brand\n */\n primaryAction?: any;\n /**\n * Slot to pass one or more elements like DBButton (e.g. profile, language, etc.) as secondary action.\n * - Desktop: Shown separated by divider at the end of the header\n * - Mobile: Shown inside the drawer at the bottom.\n */\n secondaryAction?: any;\n\n /**\n * Open/closes the drawer for mobile header or if `forceMobile` is true.\n */\n drawerOpen?: boolean | string;\n\n /**\n * Forces the header to use mobile layout for desktop as well.\n * You should only use this setting if you really can't provide a smaller navigation.\n * Overwrite size of the drawer with '--db-drawer-max-width: xxx'\n */\n forceMobile?: boolean | string;\n\n /**\n * This attribute sets the label for the burger menu button for mobile headers.\n */\n burgerMenuLabel?: string;\n};\n\nexport type DBHeaderProps = DBHeaderDefaultProps &\n InnerCloseButtonProps &\n GlobalProps &\n ToggleEventProps &\n ContainerWidthProps;\n\nexport type DBHeaderDefaultState = {\n forcedToMobile?: boolean;\n};\n\nexport type DBHeaderState = DBHeaderDefaultState &\n GlobalState &\n ToggleEventState<HTMLElement> &\n InitializedState &\n NavigationBehaviorState;\n", examples: ["Density", "Width", "Behavior", "Examples"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBHeader</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <header class="db-header">\n <div class="db-brand">Header</div>\n </header>\n </body>\n</html>\n' } } }, icon: { props: "import {\n GlobalProps,\n GlobalState,\n IconProps,\n TextProps\n} from '../../shared/model';\n\nexport const IconWeightList = ['16', '20', '24', '32', '48', '64'] as const;\nexport type IconWeightType = (typeof IconWeightList)[number];\n\nexport type DBIconDefaultProps = {\n variant?: string;\n weight?: IconWeightType;\n};\n\nexport type DBIconProps = DBIconDefaultProps &\n GlobalProps &\n IconProps &\n TextProps;\n\nexport type DBIconDefaultState = {};\n\nexport type DBIconState = DBIconDefaultState & GlobalState;\n", examples: ["Density"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBIcon</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <span data-icon="x_placeholder"> Icon </span>\n </body>\n</html>\n' } } }, infotext: { props: "import {\n GlobalProps,\n GlobalState,\n IconProps,\n SemanticProps,\n ShowIconProps,\n SizeProps,\n TextProps,\n WrapProps\n} from '../../shared/model';\n\nexport type DBInfotextDefaultProps = {};\n\nexport type DBInfotextProps = DBInfotextDefaultProps &\n GlobalProps &\n SemanticProps &\n IconProps &\n SizeProps &\n ShowIconProps &\n TextProps &\n WrapProps;\n\nexport type DBInfotextDefaultState = {};\n\nexport type DBInfotextState = DBInfotextDefaultState & GlobalState;\n", examples: ["Density", "Semantic", "Size", "Show Icon"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBInfotext</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <span class="db-infotext">No data-icon</span>\n <span class="db-infotext" data-icon="none">data-icon=none</span>\n <span class="db-infotext" data-icon="x_placeholder">Custom Icon</span>\n <span class="db-infotext" data-semantic="informational"\n >informational</span\n >\n <span\n class="db-infotext"\n data-icon="x_placeholder"\n data-semantic="informational"\n >Overwrite Icon in Variant</span\n >\n <span class="db-infotext" data-semantic="successful">successful</span>\n <span class="db-infotext" data-semantic="warning">warning</span>\n <span class="db-infotext" data-semantic="critical">critical</span>\n </body>\n</html>\n' } } }, input: { props: `import {
22004
+ ChangeEventProps,
22005
+ ChangeEventState,
22006
+ FocusEventProps,
22007
+ FocusEventState,
22008
+ FormMessageProps,
22009
+ FormProps,
22010
+ FormSizeProps,
22011
+ FormState,
22012
+ FormTextProps,
22013
+ FromValidState,
22014
+ GlobalProps,
22015
+ GlobalState,
22016
+ IconLeadingProps,
22017
+ IconProps,
22018
+ IconTrailingProps,
22019
+ InputEventProps,
22020
+ InputEventState,
22021
+ ShowIconLeadingProps,
22022
+ ShowIconProps,
22023
+ ShowIconTrailingProps,
22024
+ SizeType,
22025
+ ValueLabelType
22026
+ } from '../../shared/model';
22027
+
22028
+ export const InputTypeList = [
22029
+ 'color',
22030
+ 'date',
22031
+ 'datetime-local',
22032
+ 'email',
22033
+ 'file', // TODO: move this to own component
22034
+ 'hidden',
22035
+ 'month',
22036
+ 'number',
22037
+ 'password',
22038
+ 'range', // TODO: move this to own component
22039
+ 'search',
22040
+ 'tel',
22041
+ 'text',
22042
+ 'time',
22043
+ 'url',
22044
+ 'week'
22045
+ ] as const;
22046
+ export type InputTypeType = (typeof InputTypeList)[number];
22047
+
22048
+ export type DBInputDefaultProps = {
22049
+ /**
22050
+ * Set a [data list](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) via attribute instead of children.
22051
+ */
22052
+ dataList?: string[] | ValueLabelType[];
22053
+ /**
22054
+ * Add a custom id to [data list](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) if you're using \`dataList\` attribute.
22055
+ */
22056
+ dataListId?: string;
22057
+ /**
22058
+ * Allow selecting multiple files. https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/file#multiple
22059
+ */
22060
+ multiple?: boolean | string;
22061
+ /**
22062
+ * Specifies the types of files that the server accepts (for type="file"). https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
22063
+ */
22064
+ accept?: string;
22065
+ /**
22066
+ * Maximum value
22067
+ */
22068
+ max?: number | string;
22069
+ /**
22070
+ * Minimum value
22071
+ */
22072
+ min?: number | string;
22073
+
22074
+ /**
22075
+ * Pattern the value must match to be valid
22076
+ */
22077
+ pattern?: string;
22078
+ /**
22079
+ * Type of form control
22080
+ */
22081
+ type?: InputTypeType | string;
22082
+ /**
22083
+ * Sets [step value](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/step).
22084
+ */
22085
+ step?: number | string;
22086
+ /**
22087
+ * Hint for the [enter key behavior](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint) on virtual keyboards.
22088
+ */
22089
+ enterkeyhint?:
22090
+ | 'enter'
22091
+ | 'done'
22092
+ | 'go'
22093
+ | 'next'
22094
+ | 'previous'
22095
+ | 'search'
22096
+ | 'send';
22097
+ /**
22098
+ * Hint for [virtual keyboard](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode) selection.
22099
+ */
22100
+ inputmode?:
22101
+ | 'none'
22102
+ | 'text'
22103
+ | 'decimal'
22104
+ | 'numeric'
22105
+ | 'tel'
22106
+ | 'search'
22107
+ | 'email'
22108
+ | 'url';
22109
+ /**
22110
+ * The size of the message infotext. Defaults to "small".
22111
+ */
22112
+ messageSize?: SizeType;
22113
+ /**
22114
+ * The size of the valid message infotext. Defaults to "small".
22115
+ */
22116
+ validMessageSize?: SizeType;
22117
+ /**
22118
+ * The size of the invalid message infotext. Defaults to "small".
22119
+ */
22120
+ invalidMessageSize?: SizeType;
22121
+ };
22122
+
22123
+ export type DBInputProps = DBInputDefaultProps &
22124
+ GlobalProps &
22125
+ FormTextProps &
22126
+ InputEventProps<HTMLInputElement> &
22127
+ ChangeEventProps<HTMLInputElement> &
22128
+ FocusEventProps<HTMLInputElement> &
22129
+ FormProps &
22130
+ IconProps &
22131
+ IconTrailingProps &
22132
+ FormMessageProps &
22133
+ ShowIconProps &
22134
+ IconLeadingProps &
22135
+ ShowIconLeadingProps &
22136
+ ShowIconTrailingProps &
22137
+ FormSizeProps;
22138
+
22139
+ export type DBInputDefaultState = {
22140
+ _dataListId?: string;
22141
+ getDataList: () => ValueLabelType[];
22142
+ };
22143
+
22144
+ export type DBInputState = DBInputDefaultState &
22145
+ GlobalState &
22146
+ InputEventState<HTMLInputElement> &
22147
+ ChangeEventState<HTMLInputElement> &
22148
+ FocusEventState<HTMLInputElement> &
22149
+ FormState &
22150
+ FromValidState;
22151
+ `, examples: ["Density", "Variant", "Show Label", "Show Message", "State", "Disabled", "Readonly", "Validation", "Required", "Show Required Asterisk", "Show Icon Leading", "Show Icon Leading + Trailing", "Show Icon Trailing", "Example - Length", "Example - Types with min and max", "Example Floating Label", "Example - Types - Floating Label", "Datalist / Typeahead Examples"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBInput</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-input">\n <input\n type="text"\n name="username"\n aria-labelledby="username-label"\n aria-describedby="db-infotext-01"\n />\n <label for="username" id="username-label" aria-hidden="true">\n Label\n </label>\n <span class="db-infotext" id="db-infotext-01">No Icon</span>\n </div>\n <div class="db-input">\n <input\n type="text"\n name="username"\n aria-labelledby="username-label"\n aria-describedby="db-infotext-02"\n />\n <label for="username" id="username-label" aria-hidden="true">\n Label\n </label>\n <span\n class="db-infotext"\n data-semantic="informational"\n id="db-infotext-02"\n >\n informational\n </span>\n </div>\n </body>\n</html>\n' } } }, link: { props: "import {\n ClickEventProps,\n ClickEventState,\n GlobalProps,\n GlobalState,\n LinkProps,\n RoleProps,\n ShowIconProps,\n TextProps,\n WrapProps\n} from '../../shared/model';\n\nexport const LinkVariantList = ['adaptive', 'brand', 'inline'] as const;\nexport type LinkVariantType = (typeof LinkVariantList)[number];\n\nexport const LinkSizeList = ['medium', 'small'] as const;\nexport type LinkSizeType = (typeof LinkSizeList)[number];\n\nexport const LinkContentList = ['external', 'internal'] as const;\nexport type LinkContentType = (typeof LinkContentList)[number];\n\nexport type DBLinkDefaultProps = {\n /**\n * Adds a different arrow after the link to indicate external or internal link\n */\n content?: LinkContentType;\n /**\n * Change the size of the link\n */\n size?: LinkSizeType;\n /**\n * Change the styling of the link. `inline` will remove the arrow. Defaults to adaptive.\n */\n variant?: LinkVariantType;\n};\n\nexport type DBLinkProps = DBLinkDefaultProps &\n GlobalProps &\n ClickEventProps<HTMLAnchorElement> &\n LinkProps &\n RoleProps &\n ShowIconProps &\n TextProps &\n WrapProps;\n\nexport type DBLinkDefaultState = {};\n\nexport type DBLinkState = DBLinkDefaultState &\n GlobalState &\n ClickEventState<HTMLAnchorElement>;\n", examples: ["Density", "Variant", "Disabled", "Size", "Content", "Show Icon", "Wrap", "Examples"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBLink</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <a class="db-link" href="#">Link</a>\n </body>\n</html>\n' } } }, navigation: { props: "import { GlobalProps } from '../../shared/model';\n\nexport type DBNavigationDefaultProps = {};\n\nexport type DBNavigationProps = DBNavigationDefaultProps & GlobalProps;\n\nexport type DBNavigationDefaultState = {};\n\nexport type DBNavigationState = DBNavigationDefaultState;\n", examples: ["Density"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: {} } }, "navigation-item": { props: `import {
22152
+ ClickEvent,
22153
+ ClickEventProps,
22154
+ ClickEventState,
22155
+ GlobalProps,
22156
+ GlobalState,
22157
+ IconProps,
22158
+ InitializedState,
22159
+ NavigationBackButtonProps,
22160
+ NavigationBehaviorState,
22161
+ ShowIconProps,
22162
+ TextProps,
22163
+ WidthProps,
22164
+ WrapProps
22165
+ } from '../../shared/model';
22166
+ import { NavigationItemSafeTriangle } from '../../utils/navigation';
22167
+
22168
+ export type DBNavigationItemDefaultProps = {
22169
+ /**
22170
+ * Alternative indicator for active navigation item (bold font). In contrast to the use of aria-current="page" on the contained anchor, this does not guarantee correct a11y.
22171
+ */
22172
+ active?: boolean;
22173
+
22174
+ /**
22175
+ * The disabled attribute can be set to [keep a user from clicking on the item](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled).
22176
+ */
22177
+ disabled?: boolean | string;
22178
+
22179
+ /**
22180
+ * React-specific property to pass in a slot for sub-navigation
22181
+ */
22182
+
22183
+ subNavigation?: any;
22184
+
22185
+ /**
22186
+ * This is for mobile navigation only, if it is set the sub-navigation is a static overlay
22187
+ */
22188
+ subNavigationExpanded?: boolean | string;
22189
+ };
22190
+
22191
+ export type DBNavigationItemProps = DBNavigationItemDefaultProps &
22192
+ GlobalProps &
22193
+ ClickEventProps<HTMLButtonElement> &
22194
+ IconProps &
22195
+ WidthProps &
22196
+ WrapProps &
22197
+ NavigationBackButtonProps &
22198
+ ShowIconProps &
22199
+ TextProps;
22200
+
22201
+ export type DBNavigationItemDefaultState = {
22202
+ handleBackClick: (event: ClickEvent<HTMLButtonElement>) => void;
22203
+ hasAreaPopup: boolean;
22204
+ isSubNavigationExpanded: boolean;
22205
+
22206
+ /**
22207
+ * Internal state property to show/hide sub-navigation button
22208
+ */
22209
+ hasSubNavigation?: boolean;
22210
+ navigationItemSafeTriangle?: NavigationItemSafeTriangle;
22211
+ autoClose?: boolean;
22212
+ subNavigationId?: string;
22213
+ subNavigationToggleId?: string;
22214
+ };
22215
+
22216
+ export type DBNavigationItemState = DBNavigationItemDefaultState &
22217
+ ClickEventState<HTMLButtonElement> &
22218
+ GlobalState &
22219
+ InitializedState &
22220
+ NavigationBehaviorState;
22221
+ `, examples: ["Density", "Disabled", "Active", "Expanded", "Show Icon", "Width", "Wrap"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: {} } }, notification: { props: `import {
22222
+ ClickEvent,
22223
+ CloseEventProps,
22224
+ CloseEventState,
22225
+ GlobalProps,
22226
+ GlobalState,
22227
+ IconProps,
22228
+ InnerCloseButtonProps,
22229
+ RoleProps,
22230
+ SemanticProps,
22231
+ ShowIconProps,
22232
+ TextProps
22233
+ } from '../../shared/model';
22234
+
22235
+ export const NotificationVariantList = [
22236
+ 'docked',
22237
+ 'standalone',
22238
+ 'overlay'
22239
+ ] as const;
22240
+ export type NotificationVariantType = (typeof NotificationVariantList)[number];
22241
+
22242
+ export const NotificationLinkVariantList = ['block', 'inline'] as const;
22243
+ export type NotificationLinkVariantType =
22244
+ (typeof NotificationLinkVariantList)[number];
22245
+
22246
+ export const NotificationAriaLiveList = ['assertive', 'polite', 'off'] as const;
22247
+ export type NotificationAriaLiveType =
22248
+ (typeof NotificationAriaLiveList)[number];
22249
+
22250
+ export type DBNotificationDefaultProps = {
22251
+ /**
22252
+ * The arialive attribute will lead to that the screenreader interrupts immediately
22253
+ * and reads out the notification if set to "assertive", while it will wait for the
22254
+ * user's idleness when set to "polite", compare to [aria-live](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live)
22255
+ */
22256
+ ariaLive?: NotificationAriaLiveType;
22257
+
22258
+ /**
22259
+ * The closeable attribute shows/hides the close button on the top right.
22260
+ */
22261
+ closeable?: boolean | string;
22262
+
22263
+ /**
22264
+ * The headline attribute changes the text of the bold headline.
22265
+ */
22266
+ headline?: string | any;
22267
+
22268
+ /**
22269
+ * The slotImage can be set instead of an icon.
22270
+ */
22271
+ image?: any;
22272
+
22273
+ /**
22274
+ * The slotLink can be set for non overlay-notifications
22275
+ */
22276
+ link?: any;
22277
+
22278
+ /**
22279
+ * The linkVariant will be used if slotLink is set.
22280
+ */
22281
+ linkVariant?: NotificationLinkVariantType;
22282
+
22283
+ /**
22284
+ * Enables or disables the visibility of the headline.
22285
+ */
22286
+ showHeadline?: boolean | string;
22287
+
22288
+ /**
22289
+ * The timestamp attribute can be set for overlay notifications
22290
+ */
22291
+ timestamp?: string;
22292
+
22293
+ /**
22294
+ * Enables or disables the visibility of the timestamp.
22295
+ */
22296
+ showTimestamp?: boolean | string;
22297
+
22298
+ /**
22299
+ * The variant attribute changes the styling of the notification.
22300
+ * - The docked notifications are used e.g. between header and main content to show a global alert.
22301
+ * - The standalone notifications are used e.g. inside a form to show an alert for a specific field.
22302
+ * - The overlay notifications are used for absolute and floating notifications like snackbars etc.
22303
+ */
22304
+ variant?: NotificationVariantType;
22305
+ };
22306
+
22307
+ export type DBNotificationProps = DBNotificationDefaultProps &
22308
+ GlobalProps &
22309
+ RoleProps &
22310
+ CloseEventProps<ClickEvent<HTMLButtonElement>> &
22311
+ IconProps &
22312
+ SemanticProps &
22313
+ InnerCloseButtonProps &
22314
+ ShowIconProps &
22315
+ TextProps;
22316
+
22317
+ export type DBNotificationDefaultState = {};
22318
+
22319
+ export type DBNotificationState = DBNotificationDefaultState &
22320
+ GlobalState &
22321
+ CloseEventState<ClickEvent<HTMLButtonElement>>;
22322
+ `, examples: ["Density", "Variant", "Semantic", "Closeable", "Visual", "Show Icon", "Link Variant", "Show Headline", "Show Timestamp", "Examples - Variant:Docked", "Examples - Variant:Standalone", "Examples - Variant:Overlay"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBNotification</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-notification" data-icon="x_placeholder">\n <strong class="db-notification-headline">Headline</strong>\n <button\n class="db-button is-icon-text-replace db-notification-close"\n data-size="small"\n data-variant="ghost"\n data-icon="cross"\n >\n Close Button\n </button>\n <p class="db-notification-content">Custom Icon</p>\n </div>\n <div class="db-notification" data-semantic="informational">\n <strong class="db-notification-headline">Headline</strong>\n <button\n class="db-button is-icon-text-replace db-notification-close"\n data-size="small"\n data-variant="ghost"\n data-icon="cross"\n >\n Close Button\n </button>\n <p class="db-notification-content">informational</p>\n </div>\n <div\n class="db-notification"\n data-semantic="informational"\n data-icon="x_placeholder"\n >\n <strong class="db-notification-headline">Headline</strong>\n <button\n class="db-button is-icon-text-replace db-notification-close"\n data-size="small"\n data-variant="ghost"\n data-icon="cross"\n >\n Close Button\n </button>\n <p class="db-notification-content">Overwrite Icon in Variant</p>\n </div>\n </body>\n</html>\n' } } }, page: { props: "import { GlobalProps, GlobalState } from '../../shared/model';\n\nexport const PageVariantList = ['auto', 'fixed'] as const;\nexport type PageVariantType = (typeof PageVariantList)[number];\n\nexport const PageDocumentOverflowList = ['hidden', 'auto'] as const;\nexport type PageDocumentOverflowType =\n (typeof PageDocumentOverflowList)[number];\n\nexport type DBPageDefaultProps = {\n /**\n * The documentOverflow sets the overflow:hidden/auto to the root document\n */\n documentOverflow?: PageDocumentOverflowType;\n /**\n * Set this to have a transition with opacity to avoid layout-shifts https://simonhearne.com/2021/layout-shifts-webfonts/\n */\n fadeIn?: boolean | string;\n\n /**\n * The slot can be used for React to set a footer.\n */\n footer?: any;\n /**\n * The slot can be used for React to set a header.\n */\n header?: any;\n\n /**\n * Adds `class` to `<main>` element\n */\n mainClass?: string;\n\n /**\n * The variant=fixed uses flex-box to make header and footer static\n */\n variant?: PageVariantType;\n};\n\nexport type DBPageProps = DBPageDefaultProps & GlobalProps;\n\nexport type DBPageDefaultState = {\n fontsLoaded?: boolean;\n};\n\nexport type DBPageState = DBPageDefaultState & GlobalState;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: {} } }, popover: { props: "import {\n GapProps,\n GlobalProps,\n GlobalState,\n InitializedState,\n PlacementProps,\n PopoverProps,\n PopoverState,\n SpacingProps\n} from '../../shared/model';\n\nexport type DBPopoverDefaultProps = {\n /**\n * Use open to disable the default hover/focus behavior to use it on click or other trigger.\n */\n open?: boolean | string;\n\n /**\n * The trigger to open the popover e.g. a button\n */\n trigger?: any;\n};\n\nexport type DBPopoverProps = DBPopoverDefaultProps &\n GlobalProps &\n SpacingProps &\n PlacementProps &\n GapProps &\n PopoverProps;\n\nexport type DBPopoverDefaultState = {\n isExpanded?: boolean;\n getTrigger: () => Element | null;\n};\n\nexport type DBPopoverState = DBPopoverDefaultState &\n GlobalState &\n PopoverState &\n InitializedState;\n", examples: ["Density", "Spacing", "Placement", "Gap", "Animation", "Delay", "Width"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBPopover</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <h2>Default</h2>\n <div class="db-stack" data-direction="row" style="overflow: unset">\n <div id="popover-00" class="db-popover">\n <button class="db-button" type="button">right</button>\n <article\n class="db-popover-content"\n data-placement="right"\n data-animation="true"\n >\n <button class="db-button" type="button">\n Inside Popover\n </button>\n </article>\n </div>\n <div id="popover-01" class="db-popover">\n <button class="db-button" type="button">bottom</button>\n <article class="db-popover-content" data-animation="true">\n <button class="db-button" type="button">\n Inside Popover\n </button>\n </article>\n </div>\n <div id="popover-02" class="db-popover">\n <button class="db-button" type="button">top</button>\n <article\n class="db-popover-content"\n data-placement="top"\n data-animation="true"\n >\n <button class="db-button" type="button">\n Inside Popover\n </button>\n </article>\n </div>\n <div id="popover-02" class="db-popover">\n <button class="db-button" type="button">left</button>\n <article\n class="db-popover-content"\n data-placement="left"\n data-animation="true"\n >\n <button class="db-button" type="button">\n Inside Popover\n </button>\n </article>\n </div>\n </div>\n </body>\n</html>\n' } } }, radio: { props: "import {\n ChangeEventProps,\n ChangeEventState,\n FocusEventProps,\n FocusEventState,\n FormCheckProps,\n FormProps,\n FormState,\n GlobalProps,\n GlobalState,\n InitializedState,\n InputEventProps,\n InputEventState,\n SizeProps\n} from '../../shared/model';\n\nexport type DBRadioDefaultProps = {};\n\nexport type DBRadioProps = DBRadioDefaultProps &\n GlobalProps &\n InputEventProps<HTMLInputElement> &\n ChangeEventProps<HTMLInputElement> &\n FocusEventProps<HTMLInputElement> &\n FormProps &\n FormCheckProps &\n SizeProps;\n\nexport type DBRadioDefaultState = {};\n\nexport type DBRadioState = DBRadioDefaultState &\n GlobalState &\n InputEventState<HTMLInputElement> &\n ChangeEventState<HTMLInputElement> &\n FocusEventState<HTMLInputElement> &\n FormState &\n InitializedState;\n", examples: ["Density", "Disabled", "Checked", "Validation", "Size", "Required", "Show Label", "Show Required Asterisk"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBRadio</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <input\n type="radio"\n class="db-radio"\n id="radio-element"\n name="States"\n value="Y"\n />\n <label for="radio-element">Label</label>\n </body>\n</html>\n' } } }, section: { props: "import {\n ContainerWidthProps,\n GlobalProps,\n SpacingProps\n} from '../../shared/model';\n\nexport type DBSectionDefaultProps = {};\n\nexport type DBSectionProps = DBSectionDefaultProps &\n GlobalProps &\n SpacingProps &\n ContainerWidthProps;\n", examples: ["Density", "Width", "Spacing"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBSection</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <section class="db-section">\n <div data-variant="full">Section</div>\n </section>\n </body>\n</html>\n' } } }, select: { props: "import {\n ChangeEventProps,\n ChangeEventState,\n ClickEventProps,\n ClickEventState,\n FocusEventProps,\n FocusEventState,\n FormMessageProps,\n FormProps,\n FormSizeProps,\n FormState,\n FromValidState,\n GlobalProps,\n GlobalState,\n IconProps,\n InitializedState,\n InputEventProps,\n InputEventState,\n ShowIconProps\n} from '../../shared/model';\n\nexport type DBSelectDefaultProps = {\n /**\n * @deprecated\n * Enables multiple select, but it isn't styled, please use DBCustomSelect/db-custom-select instead\n */\n multiple?: boolean;\n\n /**\n * If you don't/can't use children/slots you can pass in the options as an array.\n */\n options?: DBSelectOptionType[];\n\n /**\n * Controls whether the empty placeholder option is shown in the dropdown after the user's selection of another option.\n * By default, it is shown for non-required selects and hidden for required selects.\n * Set to `true` to always show or `false` to always hide the empty option.\n *\n * Note: The empty option is only rendered when `variant === 'floating'` or a `placeholder` is set.\n * Setting `showEmptyOption` alone has no effect if neither of these conditions is met.\n */\n showEmptyOption?: boolean;\n};\n\nexport type DBSelectOptionType = {\n /**\n * Identifier for option\n */\n id?: string;\n\n /**\n * Disables this option\n */\n disabled?: boolean;\n\n /**\n * Selects this option\n */\n selected?: boolean;\n\n /**\n * If the value is different from the label you want to show to the user.\n */\n label?: string;\n\n /**\n * If you want to use optgroup you can nest options here.\n */\n options?: DBSelectOptionType[];\n\n /**\n * The main value you select, will be shown as default label if no label is set.\n */\n value: string | string[] | number;\n};\n\nexport type DBSelectProps = GlobalProps &\n ClickEventProps<HTMLSelectElement> &\n ChangeEventProps<HTMLSelectElement> &\n FocusEventProps<HTMLSelectElement> &\n InputEventProps<HTMLSelectElement> &\n FormProps &\n IconProps &\n FormMessageProps &\n DBSelectDefaultProps &\n ShowIconProps &\n FormSizeProps;\n\nexport type DBSelectDefaultState = {\n _placeholderId: string;\n getOptionLabel: (option: DBSelectOptionType) => string;\n shouldShowEmptyOption: () => boolean;\n};\n\nexport type DBSelectState = DBSelectDefaultState &\n GlobalState &\n ClickEventState<HTMLSelectElement> &\n ChangeEventState<HTMLSelectElement> &\n FocusEventState<HTMLSelectElement> &\n InputEventState<HTMLSelectElement> &\n FormState &\n InitializedState &\n FromValidState;\n", examples: ["Density", "Variant", "Show Label", "Show Message", "State", "Validation", "Disabled", "Content", "Required", "Show Required Asterisk", "Option Groups", "Examples Floating Label"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBSelect</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-select">\n <label for="test1">Label</label>\n <select id="test1" aria-describedby="db-infotext-01">\n <option class="placeholder" value=""></option>\n <option value="test1">Test1</option>\n <option value="test2">Test2</option>\n <option value="test3">Test3</option>\n <option value="test4">Test4</option>\n <option value="test5">Test5</option>\n </select>\n <span class="db-infotext" id="db-infotext-01">No Icon</span>\n </div>\n <div class="db-select">\n <label for="test2">Label</label>\n <select id="test2" aria-describedby="db-infotext-02">\n <option class="placeholder" value=""></option>\n <option value="test1">Test1</option>\n <option value="test2">Test2</option>\n <option value="test3">Test3</option>\n <option value="test4">Test4</option>\n <option value="test5">Test5</option>\n </select>\n <span\n class="db-infotext"\n data-semantic="informational"\n id="db-infotext-02"\n >\n informational\n </span>\n </div>\n <div class="db-select">\n <label for="test3">With optgroups</label>\n <select id="test3" aria-describedby="db-infotext-03">\n <optgroup label="Group 1">\n <option value="group1-option1">Group 1 Option 1</option>\n <option value="group1-option2">Group 1 Option 2</option>\n </optgroup>\n <optgroup label="Group 2">\n <option value="group2-option1">Group 2 Option 1</option>\n <option value="group2-option2">Group 2 Option 2</option>\n </optgroup>\n </select>\n <span class="db-infotext" id="db-infotext-03">With optgroups</span>\n </div>\n </body>\n</html>\n' } } }, stack: { props: `import { GapSpacingProps, GlobalProps, GlobalState } from '../../shared/model';
22323
+
22324
+ export const StackVariantList = ['simple', 'divider'] as const;
22325
+ export type StackVariantType = (typeof StackVariantList)[number];
22326
+
22327
+ export const StackDirectionList = ['row', 'column'] as const;
22328
+ export type StackDirectionType = (typeof StackDirectionList)[number];
22329
+
22330
+ export const StackAlignmentList = [
22331
+ 'stretch',
22332
+ 'start',
22333
+ 'end',
22334
+ 'center'
22335
+ ] as const;
22336
+ export type StackAlignmentType = (typeof StackAlignmentList)[number];
22337
+
22338
+ export const StackJustifyContentList = [
22339
+ 'space-between',
22340
+ 'start',
22341
+ 'end',
22342
+ 'center'
22343
+ ] as const;
22344
+ export type StackJustifyContentType = (typeof StackJustifyContentList)[number];
22345
+
22346
+ export type DBStackDefaultProps = {
22347
+ /**
22348
+ * Change variant of stack. To use variant="divider" add a DBDivider after each element
22349
+ */
22350
+ variant?: StackVariantType;
22351
+ /**
22352
+ * Set the direction of the stack. Defaults to "column"
22353
+ */
22354
+ direction?: StackDirectionType;
22355
+ /**
22356
+ * If the stack should wrap if parent is too small otherwise you get an overflow
22357
+ */
22358
+ wrap?: boolean | string;
22359
+ /**
22360
+ * Represents css align-items
22361
+ */
22362
+ alignment?: StackAlignmentType;
22363
+ /**
22364
+ * Represents css justify-content
22365
+ */
22366
+ justifyContent?: StackJustifyContentType;
22367
+ };
22368
+
22369
+ export type DBStackProps = DBStackDefaultProps & GlobalProps & GapSpacingProps;
22370
+
22371
+ export type DBStackDefaultState = {};
22372
+
22373
+ export type DBStackState = DBStackDefaultState & GlobalState;
22374
+ `, examples: ["Density", "Variant", "Gap", "Direction", "Wrap", "Alignment Column", "Alignment Row", "Justify Content Column", "Justify Content Row"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBStack</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-stack">Test</div>\n </body>\n</html>\n' } } }, switch: { props: "import {\n ChangeEventProps,\n ChangeEventState,\n FocusEventProps,\n FocusEventState,\n FormCheckProps,\n FormMessageProps,\n FormProps,\n FormState,\n FromValidState,\n GeneralKeyboardEvent,\n GlobalProps,\n GlobalState,\n IconLeadingProps,\n IconProps,\n IconTrailingProps,\n LabelVariantHorizontalType,\n SizeProps\n} from '../../shared/model';\n\nexport type DBSwitchDefaultProps = {\n /**\n * Add additional icons to indicate active/inactive state.\n */\n visualAid?: boolean | string;\n\n /**\n * Change the variant of the label to `trailing` or `leading`. Defaults to `trailing`\n */\n variant?: LabelVariantHorizontalType;\n};\n\nexport type DBSwitchProps = GlobalProps &\n ChangeEventProps<HTMLInputElement> &\n FocusEventProps<HTMLInputElement> &\n FormProps &\n FormCheckProps &\n Omit<FormMessageProps, 'variant'> &\n SizeProps &\n IconProps &\n IconTrailingProps &\n IconLeadingProps &\n DBSwitchDefaultProps;\n\nexport type DBSwitchDefaultState = {\n handleKeyDown: (event: GeneralKeyboardEvent<HTMLInputElement>) => void;\n};\n\nexport type DBSwitchState = DBSwitchDefaultState &\n GlobalState &\n ChangeEventState<HTMLInputElement> &\n FocusEventState<HTMLInputElement> &\n FormState &\n FromValidState;\n", examples: ["Density", "Checked", "Disabled", "Visual Aid", "Size", "Variant", "Show Label", "Required", "Show Required Asterisk", "Validation", "Show Message", "Examples"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBSwitch</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-switch">Test</div>\n </body>\n</html>\n' } } }, "tab-item": { props: "import {\n ActiveProps,\n ChangeEventProps,\n ChangeEventState,\n GlobalProps,\n GlobalState,\n IconLeadingProps,\n IconProps,\n IconTrailingProps,\n InitializedState,\n NameProps,\n NameState,\n ShowIconLeadingProps,\n ShowIconProps,\n ShowIconTrailingProps\n} from '../../shared/model';\n\nexport type DBTabItemDefaultProps = {\n /**\n * To control the component\n */\n checked?: boolean | string;\n\n /**\n * The disabled attribute can be set to keep a user from clicking on the tab-item.\n */\n disabled?: boolean | string;\n /**\n * The label of the tab-item, if you don't want to use children.\n */\n label?: string;\n /**\n * Define the text next to the icon specified via the icon Property to get hidden.\n */\n noText?: boolean | string;\n};\n\nexport type DBTabItemProps = GlobalProps &\n DBTabItemDefaultProps &\n IconProps &\n IconTrailingProps &\n IconLeadingProps &\n ShowIconLeadingProps &\n ShowIconTrailingProps &\n ActiveProps &\n ChangeEventProps<HTMLInputElement> &\n ShowIconProps &\n NameProps;\n\nexport type DBTabItemDefaultState = {\n _selected: boolean;\n _listenerAdded: boolean;\n boundSetSelectedOnChange?: (event: any) => void;\n setSelectedOnChange: (event: any) => void;\n};\n\nexport type DBTabItemState = DBTabItemDefaultState &\n GlobalState &\n ChangeEventState<HTMLInputElement> &\n InitializedState &\n NameState;\n", examples: ["Density", "States", "Show Icon Leading", "Show Icon Trailing", "Behavior", "Content Alignment Full Width"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTabItem</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <label class="db-tab-item" htmlFor="test1" role="tab">\n <input type="radio" name="test" id="test1" />\n label 1\n </label>\n\n <label class="db-tab-item" htmlFor="test2" role="tab">\n <input type="radio" name="test" id="test2" checked />\n active\n </label>\n\n <label\n class="db-tab-item"\n htmlFor="test3"\n role="tab"\n data-icon="x_placeholder"\n >\n <input type="radio" name="test" id="test3" />\n icon - text (leading)\n </label>\n\n <label\n class="db-tab-item"\n htmlFor="test4"\n role="tab"\n data-icon-trailing="x_placeholder"\n >\n <input type="radio" name="test" id="test4" />\n text - icon (trailing)\n </label>\n\n <label\n class="db-tab-item"\n htmlFor="test5"\n role="tab"\n data-icon="x_placeholder"\n data-no-text="true"\n >\n <input type="radio" name="test" id="test5" />\n </label>\n\n <label class="db-tab-item" htmlFor="test6" role="tab" data-width="full">\n <input type="radio" name="test" id="test6" />\n width (full)\n </label>\n\n <label\n class="db-tab-item"\n htmlFor="test7"\n role="tab"\n data-width="full"\n data-alignment="center"\n >\n <input type="radio" name="test" id="test7" />\n width full (centered)\n </label>\n </body>\n</html>\n' } } }, "tab-list": { props: "import { GlobalProps } from '../../shared/model';\n\nexport type DBTabListDefaultProps = {};\n\nexport type DBTabListProps = DBTabListDefaultProps & GlobalProps;\n\nexport type DBTabListDefaultState = {};\n\nexport type DBTabListState = DBTabListDefaultState;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTabList</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <h1>Horizontal</h1>\n <div\n class="db-tab-list"\n data-orientation="horizontal"\n aria-orientation="horizontal"\n >\n <label class="db-tab" htmlFor="test1" role="tab">\n <input type="radio" name="test" id="test1" />\n label 1\n </label>\n\n <label class="db-tab" htmlFor="test2" role="tab">\n <input type="radio" name="test" id="test2" checked />\n active\n </label>\n\n <label\n class="db-tab"\n htmlFor="test3"\n role="tab"\n data-icon="x_placeholder"\n >\n <input type="radio" name="test" id="test3" />\n icon - text (leading)\n </label>\n\n <label\n class="db-tab"\n htmlFor="test4"\n role="tab"\n data-icon-trailing="x_placeholder"\n >\n <input type="radio" name="test" id="test4" />\n text - icon (trailing)\n </label>\n </div>\n\n <h1>Vertical</h1>\n <div\n class="db-tab-list"\n data-orientation="vertical"\n aria-orientation="vertical"\n >\n <label class="db-tab" htmlFor="test1v" role="tab">\n <input type="radio" name="testv" id="test1v" />\n label 1\n </label>\n\n <label class="db-tab" htmlFor="test2v" role="tab">\n <input type="radio" name="testv" id="test2v" checked />\n active\n </label>\n\n <label\n class="db-tab"\n htmlFor="test3v"\n role="tab"\n data-icon="x_placeholder"\n >\n <input type="radio" name="testv" id="test3v" />\n icon - text (leading)\n </label>\n\n <label\n class="db-tab"\n htmlFor="test4v"\n role="tab"\n data-icon-trailing="x_placeholder"\n >\n <input type="radio" name="testv" id="test4v" />\n text - icon (trailing)\n </label>\n </div>\n </body>\n</html>\n' } } }, "tab-panel": { props: "import { GlobalProps, GlobalState } from '../../shared/model';\n\nexport type DBTabPanelDefaultProps = {\n /**\n * The content if you don't want to use children.\n */\n content?: string;\n};\n\nexport type DBTabPanelProps = DBTabPanelDefaultProps & GlobalProps;\n\nexport type DBTabPanelDefaultState = {};\n\nexport type DBTabPanelState = DBTabPanelDefaultState & GlobalState;\n", examples: [], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTabPanel</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <article class="db-tab-panel" role="tabpanel">Test</article>\n </body>\n</html>\n' } } }, tabs: { props: `import {
22375
+ AlignmentProps,
22376
+ GlobalProps,
22377
+ InitializedState,
22378
+ InputEvent,
22379
+ OrientationProps,
22380
+ WidthProps
22381
+ } from '../../shared/model';
22382
+ import { DBTabItemProps } from '../tab-item/model';
22383
+ import { DBTabPanelProps } from '../tab-panel/model';
22384
+
22385
+ export const TabsBehaviorList = ['scrollbar', 'arrows'] as const;
22386
+ export type TabsBehaviorType = (typeof TabsBehaviorList)[number];
22387
+
22388
+ export const TabsInitialSelectedModeList = ['auto', 'manually'] as const;
22389
+ export type TabsInitialSelectedModeType =
22390
+ (typeof TabsInitialSelectedModeList)[number];
22391
+
22392
+ export type DBSimpleTabProps = DBTabItemProps & DBTabPanelProps;
22393
+ export type DBTabsDefaultProps = {
22394
+ /**
22395
+ * Change amount of distance if you click on an arrow, only available with behavior="arrows"
22396
+ */
22397
+ arrowScrollDistance?: number | string;
22398
+ /**
22399
+ * Show a scrollbar or buttons with arrows to navigate for horizontal tabs with overflow visible
22400
+ */
22401
+ behavior?: TabsBehaviorType;
22402
+
22403
+ /**
22404
+ * Default behavior is auto selecting the first tab, change selected tab by index
22405
+ */
22406
+ initialSelectedIndex?: number | string;
22407
+
22408
+ /**
22409
+ * Default behavior is auto selecting the first tab, disable it with 'manually'
22410
+ */
22411
+ initialSelectedMode?: TabsInitialSelectedModeType;
22412
+
22413
+ /**
22414
+ * The name of the tab bar, is required for grouping multiple tabs together. Will overwrite names from children.
22415
+ */
22416
+ name?: string;
22417
+
22418
+ /**
22419
+ * Provide simple tabs with label + text as content
22420
+ */
22421
+ tabs?: DBSimpleTabProps[] | string;
22422
+ };
22423
+
22424
+ export type DBTabsEventProps = {
22425
+ /**
22426
+ * Informs the user if the current tab index has changed.
22427
+ */
22428
+ indexChange?: (index?: number) => void;
22429
+
22430
+ /**
22431
+ * Informs the user if the current tab index has changed.
22432
+ */
22433
+ onIndexChange?: (index?: number) => void;
22434
+ /**
22435
+ * Informs the user if another tab has been selected.
22436
+ */
22437
+ onTabSelect?: (event?: InputEvent<HTMLElement>) => void;
22438
+
22439
+ /**
22440
+ * Informs the user if another tab has been selected.
22441
+ */
22442
+ tabSelect?: (event?: InputEvent<HTMLElement>) => void;
22443
+ };
22444
+
22445
+ export type DBTabsProps = DBTabsDefaultProps &
22446
+ GlobalProps &
22447
+ OrientationProps &
22448
+ WidthProps &
22449
+ AlignmentProps &
22450
+ DBTabsEventProps;
22451
+
22452
+ export type DBTabsDefaultState = {
22453
+ _name: string;
22454
+ scrollContainer?: Element | null;
22455
+ scroll: (left?: boolean) => void;
22456
+ showScrollLeft?: boolean;
22457
+ showScrollRight?: boolean;
22458
+ evaluateScrollButtons: (tabList: Element) => void;
22459
+ convertTabs: () => DBSimpleTabProps[];
22460
+ initTabList: () => void;
22461
+ initTabs: (init?: boolean) => void;
22462
+ handleChange: (event: InputEvent<HTMLElement>) => void;
22463
+ _resizeObserver?: ResizeObserver;
22464
+ };
22465
+
22466
+ export type DBTabsState = DBTabsDefaultState & InitializedState;
22467
+ `, examples: ["Density", "Orientation", "Width", "Overflow", "Examples"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTabs</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <h2>Angular Example</h2>\n <db-tabs ng-_reflect-arrow-scroll-distance="75">\n <div class="db-tabs">\n <db-tab-list>\n <div\n role="tablist"\n class="db-tab-list"\n id="tab-list-d1abe676-4c30-4219-b957-f1a397d54a0b"\n aria-orientation="horizontal"\n >\n <db-tab\n ng-_reflect-name="functional"\n ng-_reflect-index="0"\n >\n <label\n role="tab"\n class="db-tab"\n for="functional-tab-0"\n aria-controls="functional-tab-panel-0"\n data-width="auto"\n data-alignment="start"\n >\n <input\n type="radio"\n name="functional"\n id="functional-tab-0"\n />Test 1</label\n >\n </db-tab>\n <db-tab\n ng-_reflect-name="functional"\n ng-_reflect-index="1"\n >\n <label\n role="tab"\n class="db-tab"\n for="functional-tab-1"\n aria-controls="functional-tab-panel-1"\n data-width="auto"\n data-alignment="start"\n >\n <input\n type="radio"\n name="functional"\n id="functional-tab-1"\n />\n Test 2\n </label>\n </db-tab>\n <db-tab\n ng-_reflect-name="functional"\n ng-_reflect-index="2"\n >\n <label\n role="tab"\n class="db-tab"\n for="functional-tab-2"\n aria-controls="functional-tab-panel-2"\n data-width="auto"\n data-alignment="start"\n >\n <input\n type="radio"\n name="functional"\n id="functional-tab-2"\n />\n Test 3\n </label>\n </db-tab>\n </div>\n </db-tab-list>\n <db-tab-panel\n ng-_reflect-name="functional"\n ng-_reflect-index="0"\n >\n <article\n role="tabpanel"\n class="db-tab-panel"\n id="functional-tab-panel-0"\n aria-labelledby="functional-tab-0"\n >\n Tab Panel 1\n </article>\n </db-tab-panel>\n <db-tab-panel\n ng-_reflect-name="functional"\n ng-_reflect-index="1"\n >\n <article\n role="tabpanel"\n class="db-tab-panel"\n id="functional-tab-panel-1"\n aria-labelledby="functional-tab-1"\n >\n Tab Panel 2\n </article>\n </db-tab-panel>\n <db-tab-panel\n ng-_reflect-name="functional"\n ng-_reflect-index="2"\n >\n <article\n role="tabpanel"\n class="db-tab-panel"\n id="functional-tab-panel-2"\n aria-labelledby="functional-tab-2"\n >\n Tab Panel 3\n </article>\n </db-tab-panel>\n </div>\n </db-tabs>\n </body>\n</html>\n' } } }, tag: { props: `import {
22468
+ ClickEvent,
22469
+ ContentSlotProps,
22470
+ EmphasisProps,
22471
+ GlobalProps,
22472
+ GlobalState,
22473
+ IconProps,
22474
+ NoTextProps,
22475
+ OverflowProps,
22476
+ SemanticProps,
22477
+ ShowIconProps
22478
+ } from '../../shared/model';
22479
+
22480
+ export const TagBehaviorList = ['static', 'removable'] as const;
22481
+ export type TagBehaviorType = (typeof TagBehaviorList)[number];
22482
+
22483
+ export type DBTagEventsProps = {
22484
+ /**
22485
+ * If "removeButton" attribute is set this function will be called when user clicks cancel button inside the tag.
22486
+ */
22487
+ onRemove?: (event?: ClickEvent<HTMLButtonElement> | void) => void;
22488
+ /**
22489
+ * If "removeButton" attribute is set this function will be called when user clicks cancel button inside the tag.
22490
+ */
22491
+ remove?: (event?: ClickEvent<HTMLButtonElement> | void) => void;
22492
+ };
22493
+
22494
+ export type DBTagDefaultProps = {
22495
+ /**
22496
+ * Defines the behavior of the component:
22497
+ * - static: default behavior without remove button
22498
+ * - removable: add a remove button at the end of the tag
22499
+ */
22500
+ behavior?: TagBehaviorType | string;
22501
+
22502
+ /**
22503
+ * The removeButton attribute shows the cancel button.
22504
+ */
22505
+ removeButton?: string;
22506
+ /**
22507
+ * Enable/Disable icon for checkbox/radio inside tag.
22508
+ */
22509
+ showCheckState?: boolean | string;
22510
+ /**
22511
+ * Alternative for children to set content as property.
22512
+ */
22513
+ text?: string;
22514
+
22515
+ /**
22516
+ * If "interactive" is set to true, you can pass a value to the underlying checkbox or radio input.
22517
+ */
22518
+ value?: string;
22519
+ };
22520
+
22521
+ export type DBTagProps = DBTagDefaultProps &
22522
+ GlobalProps &
22523
+ IconProps &
22524
+ SemanticProps &
22525
+ OverflowProps &
22526
+ EmphasisProps &
22527
+ ShowIconProps &
22528
+ ContentSlotProps &
22529
+ DBTagEventsProps &
22530
+ NoTextProps;
22531
+
22532
+ export type DBTagDefaultState = {
22533
+ getRemoveButtonText: () => string;
22534
+ handleRemove: (event?: ClickEvent<HTMLButtonElement> | void) => void;
22535
+ };
22536
+
22537
+ export type DBTagState = DBTagDefaultState & GlobalState;
22538
+ `, examples: ["Density", "Emphasis", "Semantic", "Behavior", "Checked", "Disabled", "Show Icon", "No Text", "Show Slot", "Show Check State", "Overflow", "Example Strong"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTag</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-tag">\n <span class="tag-label">DBTag</span>\n </div>\n </body>\n</html>\n' } } }, textarea: { props: "import {\n ChangeEventProps,\n ChangeEventState,\n FocusEventProps,\n FocusEventState,\n FormMessageProps,\n FormProps,\n FormState,\n FormTextProps,\n FromValidState,\n GlobalProps,\n GlobalState,\n InputEventProps,\n InputEventState\n} from '../../shared/model';\n\nexport const TextareaResizeList = [\n 'none',\n 'both',\n 'horizontal',\n 'vertical'\n] as const;\nexport type TextareaResizeType = (typeof TextareaResizeList)[number];\n\nexport const TextareaWrapList = ['hard', 'soft', 'off'] as const;\nexport type TextareaWrapType = (typeof TextareaWrapList)[number];\n\nexport type DBTextareaDefaultProps = {\n /**\n * The visible width of the text control, in average character widths. If it is specified, it must be a positive integer\n */\n cols?: number | string;\n /**\n * In most browsers, textareas are resizable \u2014 you'll notice the drag handle in the right-hand corner, you can control it with this\n */\n resize?: TextareaResizeType;\n\n /**\n * Show/Hides drag handle in the right-hand corner - default: true\n */\n showResizer?: boolean | string;\n\n /**\n * The number of visible text lines for the control. If it is specified, it must be a positive integer\n */\n rows?: number | string;\n /**\n * Specifies whether the textarea is subject to spell checking by the underlying browser/OS\n */\n spellCheck?: boolean;\n\n /**\n * Indicates how the control should wrap the value for form submission.\n */\n wrap?: TextareaWrapType;\n};\n\nexport type DBTextareaProps = DBTextareaDefaultProps &\n ChangeEventProps<HTMLTextAreaElement> &\n InputEventProps<HTMLTextAreaElement> &\n FocusEventProps<HTMLTextAreaElement> &\n FormProps &\n GlobalProps &\n FormTextProps &\n FormMessageProps;\n\nexport type DBTextareaDefaultState = {};\n\nexport type DBTextareaState = DBTextareaDefaultState &\n ChangeEventState<HTMLTextAreaElement> &\n InputEventState<HTMLTextAreaElement> &\n FocusEventState<HTMLTextAreaElement> &\n FormState &\n GlobalState &\n FromValidState;\n", examples: ["Density", "Variant", "Show Label", "Show Message", "State", "Disabled", "Readonly", "Validation", "Required", "Show Required Asterisk", "Rows", "Show Resizer", "Field Sizing", "Examples Floating Label"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTextarea</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n\n <body style="padding: var(--db-spacing-fixed-md)">\n <div class="db-textarea">\n <label for="textarea"> Label </label>\n <textarea\n id="textarea"\n rows="2"\n cols="33"\n placeholder=" "\n aria-describedby="db-infotext-01"\n ></textarea>\n <span class="db-infotext" data-size="medium" id="db-infotext-01"\n >No icon</span\n >\n </div>\n <div class="db-textarea">\n <label for="textarea2"> Label </label>\n <textarea\n id="textarea2"\n rows="2"\n cols="33"\n placeholder=" "\n aria-describedby="db-infotext-02"\n ></textarea>\n <span\n class="db-infotext"\n data-size="medium"\n data-semantic="informational"\n id="db-infotext-02"\n >informational</span\n >\n </div>\n </body>\n</html>\n' } } }, tooltip: { props: "import {\n ClickEventState,\n DocumentScrollState,\n EmphasisProps,\n GlobalProps,\n GlobalState,\n InitializedState,\n PlacementProps,\n PopoverProps,\n PopoverState,\n ResetIdState,\n WrapProps\n} from '../../shared/model';\n\nexport const TooltipVariantList = ['description', 'label'] as const;\nexport type TooltipVariantType = (typeof TooltipVariantList)[number];\n\nexport type DBTooltipDefaultProps = {\n /**\n * Show/Hides arrow\n */\n showArrow?: boolean | string;\n /**\n * Change the behavior of the tooltip:\n * - description: Adds `aria-describedby` to parent\n * - label: Adds `aria-labelledby` to parent\n */\n variant?: TooltipVariantType;\n};\n\nexport type DBTooltipProps = DBTooltipDefaultProps &\n GlobalProps &\n EmphasisProps &\n PlacementProps &\n PopoverProps &\n WrapProps;\n\nexport type DBTooltipDefaultState = {\n getParent: () => HTMLElement;\n};\n\nexport type DBTooltipState = DBTooltipDefaultState &\n GlobalState &\n ClickEventState<HTMLElement> &\n PopoverState &\n InitializedState &\n DocumentScrollState &\n ResetIdState;\n", examples: ["Density", "Show Arrow", "Emphasis", "Placement", "Width", "Animation", "Delay"], exampleCode: { react: {}, angular: {}, vue: {}, "web-components": {}, html: { "index.html": '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>DBTooltip</title>\n <link rel="stylesheet" href="/styles/relative.css" />\n </head>\n <body style="padding: var(--db-spacing-fixed-md)">\n <h1>Placement</h1>\n <button\n class="db-button"\n aria-describedby="tooltip-01"\n data-has-tooltip="true"\n >\n Tooltip\n <i class="db-tooltip" id="tooltip-01">Test</i>\n </button>\n <button\n class="db-button"\n aria-describedby="tooltip-02"\n data-has-tooltip="true"\n >\n Tooltip top\n <i class="db-tooltip" data-placement="top" id="tooltip-02">Test</i>\n </button>\n <button\n class="db-button"\n aria-describedby="tooltip-03"\n data-has-tooltip="true"\n >\n Tooltip left\n <i class="db-tooltip" data-placement="left" id="tooltip-03">Test</i>\n </button>\n <button\n class="db-button"\n aria-describedby="tooltip-04"\n data-has-tooltip="true"\n >\n Tooltip right\n <i class="db-tooltip" data-placement="right" id="tooltip-04"\n >Test</i\n >\n </button>\n <button\n class="db-button"\n aria-describedby="tooltip-05"\n data-has-tooltip="true"\n >\n Tooltip Strong\n <i class="db-tooltip" data-emphasis="strong" id="tooltip-05"\n >Test</i\n >\n </button>\n </body>\n</html>\n' } } } }, tokens: { colors: '$variants: "neutral", "brand", "critical", "successful", "warning", "informational";\n$variant-colors: "neutral", "critical", "successful", "warning", "informational";\n$on-background-colors:\n "emphasis-100", "emphasis-90", "emphasis-80", "emphasis-70", "emphasis-60",\n "emphasis-50";\n$background-colors:\n "basic-level-1", "basic-level-2", "basic-level-3", "basic-transparent-semi",\n "basic-transparent-full";\n$inverted-colors: "contrast-max", "contrast-high", "contrast-low";\n\n// adaptive colors\n\n// bg basic\n$db-adaptive-bg-basic-level-1-default: var(\n --db-adaptive-bg-basic-level-1-default\n);\n$db-adaptive-bg-basic-level-1-hovered: var(\n --db-adaptive-bg-basic-level-1-hovered\n);\n$db-adaptive-bg-basic-level-1-pressed: var(\n --db-adaptive-bg-basic-level-1-pressed\n);\n$db-adaptive-bg-basic-level-2-default: var(\n --db-adaptive-bg-basic-level-2-default\n);\n$db-adaptive-bg-basic-level-2-hovered: var(\n --db-adaptive-bg-basic-level-2-hovered\n);\n$db-adaptive-bg-basic-level-2-pressed: var(\n --db-adaptive-bg-basic-level-2-pressed\n);\n$db-adaptive-bg-basic-level-3-default: var(\n --db-adaptive-bg-basic-level-3-default\n);\n$db-adaptive-bg-basic-level-3-hovered: var(\n --db-adaptive-bg-basic-level-3-hovered\n);\n$db-adaptive-bg-basic-level-3-pressed: var(\n --db-adaptive-bg-basic-level-3-pressed\n);\n$db-adaptive-bg-basic-transparent-full-default: var(\n --db-adaptive-bg-basic-transparent-full-default\n);\n$db-adaptive-bg-basic-transparent-semi-default: var(\n --db-adaptive-bg-basic-transparent-semi-default\n);\n$db-adaptive-bg-basic-transparent-full-hovered: var(\n --db-adaptive-bg-basic-transparent-full-hovered\n);\n$db-adaptive-bg-basic-transparent-full-pressed: var(\n --db-adaptive-bg-basic-transparent-full-pressed\n);\n$db-adaptive-bg-basic-transparent-semi-hovered: var(\n --db-adaptive-bg-basic-transparent-semi-hovered\n);\n$db-adaptive-bg-basic-transparent-semi-pressed: var(\n --db-adaptive-bg-basic-transparent-semi-pressed\n);\n\n// on-bg basic\n$db-adaptive-on-bg-basic-emphasis-100-default: var(\n --db-adaptive-on-bg-basic-emphasis-100-default\n);\n$db-adaptive-on-bg-basic-emphasis-100-hovered: var(\n --db-adaptive-on-bg-basic-emphasis-100-hovered\n);\n$db-adaptive-on-bg-basic-emphasis-100-pressed: var(\n --db-adaptive-on-bg-basic-emphasis-100-pressed\n);\n$db-adaptive-on-bg-basic-emphasis-90-default: var(\n --db-adaptive-on-bg-basic-emphasis-90-default\n);\n$db-adaptive-on-bg-basic-emphasis-90-hovered: var(\n --db-adaptive-on-bg-basic-emphasis-90-hovered\n);\n$db-adaptive-on-bg-basic-emphasis-90-pressed: var(\n --db-adaptive-on-bg-basic-emphasis-90-pressed\n);\n$db-adaptive-on-bg-basic-emphasis-80-default: var(\n --db-adaptive-on-bg-basic-emphasis-80-default\n);\n$db-adaptive-on-bg-basic-emphasis-80-hovered: var(\n --db-adaptive-on-bg-basic-emphasis-80-hovered\n);\n$db-adaptive-on-bg-basic-emphasis-80-pressed: var(\n --db-adaptive-on-bg-basic-emphasis-80-pressed\n);\n$db-adaptive-on-bg-basic-emphasis-70-default: var(\n --db-adaptive-on-bg-basic-emphasis-70-default\n);\n$db-adaptive-on-bg-basic-emphasis-70-hovered: var(\n --db-adaptive-on-bg-basic-emphasis-70-hovered\n);\n$db-adaptive-on-bg-basic-emphasis-70-pressed: var(\n --db-adaptive-on-bg-basic-emphasis-70-pressed\n);\n$db-adaptive-on-bg-basic-emphasis-60-default: var(\n --db-adaptive-on-bg-basic-emphasis-60-default\n);\n$db-adaptive-on-bg-basic-emphasis-50-default: var(\n --db-adaptive-on-bg-basic-emphasis-50-default\n);\n\n// inverted\n\n$db-adaptive-bg-inverted-contrast-max-default: var(\n --db-adaptive-bg-inverted-contrast-max-default\n);\n$db-adaptive-bg-inverted-contrast-max-hovered: var(\n --db-adaptive-bg-inverted-contrast-max-hovered\n);\n$db-adaptive-bg-inverted-contrast-max-pressed: var(\n --db-adaptive-bg-inverted-contrast-max-pressed\n);\n$db-adaptive-bg-inverted-contrast-high-default: var(\n --db-adaptive-bg-inverted-contrast-high-default\n);\n$db-adaptive-bg-inverted-contrast-high-hovered: var(\n --db-adaptive-bg-inverted-contrast-high-hovered\n);\n$db-adaptive-bg-inverted-contrast-high-pressed: var(\n --db-adaptive-bg-inverted-contrast-high-pressed\n);\n$db-adaptive-bg-inverted-contrast-low-default: var(\n --db-adaptive-bg-inverted-contrast-low-default\n);\n$db-adaptive-bg-inverted-contrast-low-hovered: var(\n --db-adaptive-bg-inverted-contrast-low-hovered\n);\n$db-adaptive-bg-inverted-contrast-low-pressed: var(\n --db-adaptive-bg-inverted-contrast-low-pressed\n);\n\n// on-bg-inverted\n$db-adaptive-on-bg-inverted-default: var(--db-adaptive-on-bg-inverted-default);\n$db-adaptive-on-bg-inverted-hovered: var(--db-adaptive-on-bg-inverted-hovered);\n$db-adaptive-on-bg-inverted-pressed: var(--db-adaptive-on-bg-inverted-pressed);\n\n// origin\n$db-adaptive-origin-default: var(--db-adaptive-origin-default);\n$db-adaptive-origin-hovered: var(--db-adaptive-origin-hovered);\n$db-adaptive-origin-pressed: var(--db-adaptive-origin-pressed);\n\n// on-origin\n$db-adaptive-on-origin-default: var(--db-adaptive-on-origin-default);\n$db-adaptive-on-origin-hovered: var(--db-adaptive-on-origin-hovered);\n$db-adaptive-on-origin-pressed: var(--db-adaptive-on-origin-pressed);\n\n// vibrant\n$db-adaptive-bg-vibrant-default: var(--db-adaptive-bg-vibrant-default);\n$db-adaptive-bg-vibrant-hovered: var(--db-adaptive-bg-vibrant-hovered);\n$db-adaptive-bg-vibrant-pressed: var(--db-adaptive-bg-vibrant-pressed);\n\n// on-vibrant\n$db-adaptive-on-bg-vibrant-default: var(--db-adaptive-on-bg-vibrant-default);\n$db-adaptive-on-bg-vibrant-hovered: var(--db-adaptive-on-bg-vibrant-hovered);\n$db-adaptive-on-bg-vibrant-pressed: var(--db-adaptive-on-bg-vibrant-pressed);\n', typography: "// Use for body tags like <p>\n\n$db-type-body-3xs: var(--db-type-body-3xs);\n$db-type-body-2xs: var(--db-type-body-2xs);\n$db-type-body-xs: var(--db-type-body-xs);\n$db-type-body-sm: var(--db-type-body-sm);\n$db-type-body-md: var(--db-type-body-md);\n$db-type-body-lg: var(--db-type-body-lg);\n$db-type-body-xl: var(--db-type-body-xl);\n$db-type-body-2xl: var(--db-type-body-2xl);\n$db-type-body-3xl: var(--db-type-body-3xl);\n\n// Use for headline tags like <h1>\n\n$db-type-headline-3xs: var(--db-type-headline-3xs);\n$db-type-headline-2xs: var(--db-type-headline-2xs);\n$db-type-headline-xs: var(--db-type-headline-xs);\n$db-type-headline-sm: var(--db-type-headline-sm);\n$db-type-headline-md: var(--db-type-headline-md);\n$db-type-headline-lg: var(--db-type-headline-lg);\n$db-type-headline-xl: var(--db-type-headline-xl);\n$db-type-headline-2xl: var(--db-type-headline-2xl);\n$db-type-headline-3xl: var(--db-type-headline-3xl);\n", spacing: "// Use sizing values for fixed heights/widths e.g. the db-button has always a fixed height\n$db-sizing-3xs: var(--db-sizing-3xs);\n$db-sizing-2xs: var(--db-sizing-2xs);\n$db-sizing-xs: var(--db-sizing-xs);\n$db-sizing-sm: var(--db-sizing-sm);\n$db-sizing-md: var(--db-sizing-md);\n$db-sizing-lg: var(--db-sizing-lg);\n$db-sizing-xl: var(--db-sizing-xl);\n$db-sizing-2xl: var(--db-sizing-2xl);\n$db-sizing-3xl: var(--db-sizing-3xl);\n\n// Use fixed spacings for all kinds of distances (margin, padding, ...)\n$db-spacing-fixed-3xs: var(--db-spacing-fixed-3xs);\n$db-spacing-fixed-2xs: var(--db-spacing-fixed-2xs);\n$db-spacing-fixed-xs: var(--db-spacing-fixed-xs);\n$db-spacing-fixed-sm: var(--db-spacing-fixed-sm);\n$db-spacing-fixed-md: var(--db-spacing-fixed-md);\n$db-spacing-fixed-lg: var(--db-spacing-fixed-lg);\n$db-spacing-fixed-xl: var(--db-spacing-fixed-xl);\n$db-spacing-fixed-2xl: var(--db-spacing-fixed-2xl);\n$db-spacing-fixed-3xl: var(--db-spacing-fixed-3xl);\n\n// The primary use-case for responsive spacings are\n// paddings/gaps in an application e.g. the <main> should have a responsive padding.\n$db-spacing-responsive-3xs: var(--db-spacing-responsive-3xs);\n$db-spacing-responsive-2xs: var(--db-spacing-responsive-2xs);\n$db-spacing-responsive-xs: var(--db-spacing-responsive-xs);\n$db-spacing-responsive-sm: var(--db-spacing-responsive-sm);\n$db-spacing-responsive-md: var(--db-spacing-responsive-md);\n$db-spacing-responsive-lg: var(--db-spacing-responsive-lg);\n$db-spacing-responsive-xl: var(--db-spacing-responsive-xl);\n$db-spacing-responsive-2xl: var(--db-spacing-responsive-2xl);\n$db-spacing-responsive-3xl: var(--db-spacing-responsive-3xl);\n\n// Elevation\n\n$db-elevation-sm: var(--db-elevation-sm);\n$db-elevation-md: var(--db-elevation-md);\n$db-elevation-lg: var(--db-elevation-lg);\n\n// Border\n\n$db-border-width-3xs: var(--db-border-width-3xs);\n$db-border-width-2xs: var(--db-border-width-2xs);\n$db-border-width-xs: var(--db-border-width-xs);\n$db-border-width-sm: var(--db-border-width-sm);\n$db-border-width-md: var(--db-border-width-md);\n$db-border-width-lg: var(--db-border-width-lg);\n$db-border-width-xl: var(--db-border-width-xl);\n$db-border-width-2xl: var(--db-border-width-2xl);\n$db-border-width-3xl: var(--db-border-width-3xl);\n$db-border-radius-3xs: var(--db-border-radius-3xs);\n$db-border-radius-2xs: var(--db-border-radius-2xs);\n$db-border-radius-xs: var(--db-border-radius-xs);\n$db-border-radius-sm: var(--db-border-radius-sm);\n$db-border-radius-md: var(--db-border-radius-md);\n$db-border-radius-lg: var(--db-border-radius-lg);\n$db-border-radius-xl: var(--db-border-radius-xl);\n$db-border-radius-2xl: var(--db-border-radius-2xl);\n$db-border-radius-3xl: var(--db-border-radius-3xl);\n$db-border-radius-full: var(--db-border-radius-full);\n\n// Opacity\n\n$db-opacity-3xs: var(--db-opacity-3xs);\n$db-opacity-2xs: var(--db-opacity-2xs);\n$db-opacity-xs: var(--db-opacity-xs);\n$db-opacity-sm: var(--db-opacity-sm);\n$db-opacity-md: var(--db-opacity-md);\n$db-opacity-lg: var(--db-opacity-lg);\n$db-opacity-xl: var(--db-opacity-xl);\n$db-opacity-2xl: var(--db-opacity-2xl);\n$db-opacity-3xl: var(--db-opacity-3xl);\n$db-opacity-full: var(--db-opacity-full);\n\n// Transitions\n\n$db-transition-duration-extra-slow: var(--db-transition-duration-extra-slow);\n$db-transition-duration-slow: var(--db-transition-duration-slow);\n$db-transition-duration-medium: var(--db-transition-duration-medium);\n$db-transition-duration-fast: var(--db-transition-duration-fast);\n$db-transition-duration-extra-fast: var(--db-transition-duration-extra-fast);\n$db-transition-timing-emotional: var(--db-transition-timing-emotional);\n$db-transition-timing-functional: var(--db-transition-timing-functional);\n$db-transition-timing-show: var(--db-transition-timing-show);\n$db-transition-timing-hide: var(--db-transition-timing-hide);\n$db-transition-straight-emotional: var(--db-transition-straight-emotional);\n$db-transition-straight-functional: var(--db-transition-straight-functional);\n$db-transition-straight-show: var(--db-transition-straight-show);\n$db-transition-straight-hide: var(--db-transition-straight-hide);\n\n// Screen sizes\n\n$db-screen-xs: var(--db-screen-xs);\n$db-screen-sm: var(--db-screen-sm);\n$db-screen-md: var(--db-screen-md);\n$db-screen-lg: var(--db-screen-lg);\n$db-screen-xl: var(--db-screen-xl);\n\n// Container sizes\n\n$db-container-3xs: var(--db-container-3xs);\n$db-container-2xs: var(--db-container-2xs);\n$db-container-xs: var(--db-container-xs);\n$db-container-sm: var(--db-container-sm);\n$db-container-md: var(--db-container-md);\n$db-container-lg: var(--db-container-lg);\n$db-container-xl: var(--db-container-xl);\n$db-container-2xl: var(--db-container-2xl);\n$db-container-3xl: var(--db-container-3xl);\n", density: '$densities: ("expressive", "regular", "functional");\n$sizings: "3xs", "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl";\n', animation: "@keyframes popover-animation {\n 0% {\n pointer-events: none;\n opacity: 0;\n transform: translate(\n var(--db-popover-center-x, var(--db-popover-translate-x, 0%)),\n var(--db-popover-center-y, var(--db-popover-translate-y, 0%))\n );\n }\n\n 100% {\n pointer-events: auto;\n opacity: 1;\n transform: translate(\n var(--db-popover-center-x, 0%),\n var(--db-popover-center-y, 0%)\n );\n }\n}\n\n@keyframes rotate {\n 100% {\n transform: rotate(1turn);\n }\n}\n", transitions: '@use "../variables";\n\n%default-transition {\n transition:\n outline #{variables.$db-transition-duration-extra-fast},\n border-color #{variables.$db-transition-straight-emotional},\n background-color #{variables.$db-transition-straight-emotional};\n}\n\n%default-fg-transition {\n transition:\n outline #{variables.$db-transition-duration-extra-fast},\n color #{variables.$db-transition-straight-emotional};\n}\n' }, docs: { "docs/adr/adr-01-framework.md": '# ADR-01 - Framework for DB UX Components\n\n## Decision and Rationale\n\nTo reduce the amount of time spent writing components for each framework, we use [Mitosis](https://github.com/BuilderIO/mitosis) to build "native" JavaScript framework components.\n\nWe chose Mitosis because it is flexible and open source. We took the risk that it is quite new at the moment.\n\n## Problem description and context\n\nWe want to ship our DB UX styles based on `css` and `scss` for common frameworks like [Angular](https://angular.io/), [React](https://reactjs.org/), [Vue](https://vuejs.org/) and so on.\n\nTo achieve this we started with [Web Components](https://github.com/db-ui/elements).\nBut we\'ve encountered a number of problems with this approach:\n\n- No auto-complete in IDE: Without `.d.ts` files you aren\'t able to use TypeScript properly\n- No specific framework solutions, for example Angular [Reactive Forms](https://angular.io/guide/reactive-forms)\n- Wrapping Components for React: Because of the virtual DOM Events need some wrapping, even [Lit](https://lit.dev/docs/frameworks/react/) needs this\n- Composition of nested Components (Accordion & AccordionItem etc.): Writing a components with Shadow DOM and nesting is complex and time-consuming\n\n## General conditions and decision criteria\n\n### General conditions\n\n- "Native" components for every framework\n- Encapsulated from styling\n- Code once, build for many\n\n### Decision Criteria\n\n- Mitosis generates `.json` files that are compiled into native components for each framework\n- Supports most frameworks and Web Components\n- New frameworks can be adopted very easily\n- Generates "real" native components for frameworks\n- Consuming Developer Experience\n- Out-of-the-box support for SSR/SSG inside popular Frameworks like [Next](https://nextjs.org/)/[Nuxt](https://nuxt.com/)\n\n#### Why did we switch from Stencil to Mitosis?\n\nBecause of the developers consuming the components. We discovered that developers don\'t feel comfortable using Web Components inside their framework (Angular, React, Vue) projects.\n\nEven with some wrappers around we didn\'t achieve a good developer experience. Therefore, the developers started to use our styles and writing custom components in their desired framework.\n\nSo we noticed the most important thing is to have a good developer experience, otherwise we don\'t get the time saving potential and consistency of a design system.\n\nTo summarize, we need "real" native components to be successful. So the only remaining option is to write the components in any popular framework or to have the components generated. We see the potential to save time by generating components with mitosis, and we have the option of integrating new frameworks relatively easily.\n\nWe still expect Web Components to be the perfect solution for the future, but especially as React doesn\'t support them so far, we\'re still blocked at the moment for a full buy-in.\n\n## Alternatives\n\n### A - Mitosis\n\n#### Evaluation\n\n- Generated artifacts are "native" to each framework\n- Flexible build system with plugins\n- Builder.io as maintainer\n- TypeScript (tsx)\n- No weird wrappers around Web Components\n\n### B - Stencil\n\n#### Evaluation\n\n- Generated artifacts are only slightly larger than Vanilla JS\n- Polyfills are handled automatically\n- Flexible build system\n- With Ionic, a larger project is behind it as a maintainer\n- Supports `Sass`\n- TypeScript\n\n## Consequences\n\n- Mitosis is still in alpha.\n- Changes may occur. This may lead to refactoring on our part.\n- There is no paid support.\n\n## Links\n\n- [Mitosis](https://github.com/BuilderIO/mitosis)\n- [Stencil](https://stenciljs.com/)\n', "docs/adr/adr-02-monorepo.md": "# ADR-02 - Monorepo\n\n## Decision and Rationale\n\nTo reduce the amount of time spent deploying and linking dependent packages, we combined [base](https://github.com/db-ui/base), [core](https://github.com/db-ui/core) and [elements](https://github.com/db-ui/elements) into a single monorepo, and evolved afterwards regarding new technologies (compare to ADR 01).\n\n## Problem description and context\n\nWe had the problem that issues inside UI elements often occurs on the token level (base).\nFor developers, it was a time-consuming task to link the projects, find and fix the issue. Sometimes base or core had to be deployed to test if the solution really works, which leads to countless hours waiting for deployments until the result was fine.\n\n## General conditions and decision criteria\n\n### General conditions\n\n- Development should be easier\n- Changes inside tokens should be tested directly in components\n- Issues inside components should be fixed in same deployment\n- Issues can be reported via 1 repository\n\n### Decision Criteria\n\n- For marketing, we just need one URL instead of three\n- Development is faster and easier\n- Team members have experience with monorepos\n\n## Consequences\n\n- Complex CI/CD\n- A lot of files, hard for new contributors\n- Time to migrate 3 repos into 1\n", "docs/adr/adr-03-dependency-automation.md": '# ADR-03 - Dependency automation\n\n## Decision and Rationale\n\nTo reduce the amount of time spent updating dependencies we want to use an automated process inside the CI/CD to update our dependencies with new versions, to reduce security issues.\n\nWe pick [dependabot](https://github.com/dependabot) because it is the default for open-source GitHub projects.\n\n## Problem description and context\n\nIf dependencies are not updated automatically, packages can outdated and provide security issues for consumers.\n\n## General conditions and decision criteria\n\n### General conditions\n\n- Dependencies should be updated inside a monorepo\n- Tool should be easy to maintain\n- Support should be backed up by a company\n\n### Decision Criteria\n\n- Dependabot maintained by GitHub\n- Lot of community features\n- Free usage of runners for open-source projects\n\n## Alternatives\n\n### A - Dependabot\n\n#### Evaluation\n\n- provided by GitHub directly\n- easier to maintain and with meaningful defaults\n\n### B - Renovate\n\n#### Evaluation\n\n- Get automated Pull Requests to update your dependencies\n- Reduce noise by running Renovate on a schedule\n- Relevant package files are discovered automatically\n- Supports monorepo architectures like Lerna or Yarn workspaces with no extra configuration\n- Bot behavior is customizable via configuration files (config as code)\n- Use ESLint-like shared config presets for ease of use and simplifying configuration (JSON format only)\n- Lock files are supported and updated in the same commit, including immediately resolving conflicts whenever PRs are merged\n- Get replacement PRs to migrate from a deprecated dependency to the community suggested replacement (npm packages only)\n- Open source (installable via npm/Yarn or Docker Hub) so can be self-hosted or used via GitHub App\n\n## Links\n\n- [Dependabot](https://github.com/dependabot)\n- [Renovate](https://github.com/renovatebot/renovate)\n\n## Implementation Details\n\n### Current Configuration\n\nThe repository uses Dependabot with the following strategy:\n\n#### Version Pinning Strategy\n\n- **All dependencies are pinned to exact versions** (no `^` or `~` prefixes) to ensure reproducible builds\n- **Peer dependencies** maintain ranges for compatibility (e.g., `"stylelint": "^14.0.0 || ^15.0.0 || ^16.0.0"`)\n- **Internal workspace dependencies** use `"*"` for monorepo flexibility\n- **Versioning strategy**: `increase` ensures all updates generate pull requests\n\n#### Automation Levels\n\n1. **Patch updates**: Automatically approved and merged via GitHub Actions\n2. **Minor updates**: Grouped by technology/framework, require manual review\n3. **Major updates**: Blocked for critical dependencies (Angular, React, TypeScript) requiring manual coordination\n\n#### Dependency Grouping\n\nDependencies are logically grouped to reduce PR noise:\n\n- **Framework groups**: Angular, React, Next.js\n- **Tool groups**: ESLint, Stylelint, Prettier, TypeScript, Vite\n- **Testing groups**: Playwright, Vitest\n- **Development tools**: Commitlint\n- **Patch group**: All patch updates bundled together\n\n#### Schedule and Timing\n\n- **Daily runs at 23:00 Europe/Berlin timezone**\n- **Pull request limit**: 10 concurrent PRs to avoid overwhelming maintainers\n\n#### Ignored Dependencies\n\nCertain dependencies are intentionally ignored for manual control:\n\n- Angular major versions (coordinated framework updates)\n- React major versions (coordinated framework updates)\n- TypeScript major versions (requires codebase compatibility review)\n- Sass (temporary due to compatibility issues)\n- ESLint v9 major (pending migration planning)\n- Zone.js minor versions (Angular LTS compatibility)\n', "docs/adr/adr-04-icons.md": "# ADR-04 - How to handle functional icons\n\n_WIP_\n\n## Decision and justification\n\nWe'll provide both SVG files, as well as icon fonts for total flexibility by the consuming developers. Out of our system we're focusing on using the latter, as this simplifies problems regarding e.g. referencing the assets at the correct path.\n\nIn general, these would be the ways how to reference a functional icon:\n\n- Icons that we'd like to set based on the guidelines (like a specific icon for a specific variant, type or whatever): Via SCSS mixin, especially to separate markup from styling, and to ensure non-breaking update feasibility.\n- Icons that the user could set: Either via SCSS mixin, or HTML attribute `data-icon`, depending on their tech stack.\n\n## Problem description and context\n\n## General conditions and decision criteria\n\n### General conditions\n\n### Decision criteria\n\n- ...\n\n## Alternatives\n\n### A - Alternative name\n\n#### Evaluation\n\n### B - Alternative name\n\n#### Evaluation\n\n## Consequences\n\n## Links\n", "docs/adr/adr-05-copilot-developer-doc.md": '# ADR 2025-06-10: Documentation strategy for GitHub Copilot and developer docs\n\n## Context\n\nWe need a consistent, maintainable documentation approach that serves both developers and AI-assisted coding\ntools (GitHub Copilot) without duplicating effort. The documentation must cover component usage, variants, props,\nexamples, and allow Copilot to answer questions like "What variants does the Button support?" without manually\nopening multiple files.\n\nKey requirements:\n\n- Single source of truth for component documentation.\n- Automatic inclusion of context in Copilot Chat for both IDEs, VS Code and IntelliJ.\n- Developer-friendly Markdown for manual reading and static site generation.\n- Compatibility with LLM context conventions (llms.txt; to be integrated in a later phase) and GitHub Copilot Custom Instructions (`copilot-instructions.md`).\n\n## Decision\n\n1. Documentation Format & Location\n - Use Markdown files per component, stored in packages/components/docs/ or packages/components/src/components/docs/.\n - Central table of contents in docs/llms.txt listing all component docs with relative paths.\n\n2. GitHub Copilot Custom Instructions\n - Place `copilot-instructions.md` in the project root (under .github/) to provide global guidance.\n - Instruct Copilot Chat to load this file automatically; it will include links to llms.txt and recommended file paths.\n\n3. Automatic Context Loading\n - In VS Code and IntelliJ, Copilot Chat will automatically read `.github/copilot-instructions.md` on new chats.\n - To surface specific details, embed documentation (e.g., Button.md) directly in `copilot-instructions.md`.\n\n4. Interactive Context Attachment\n - For deeper or ad-hoc queries, use the "Attach Context" feature in Copilot Chat to load component Markdown files during the session.\n\n5. Static Site & Developer Docs (future usage, not part of the current scope)\n - Integrate component docs via Astro as a package in the monorepo, referencing Markdown sources in packages/components/... .\n - Render pages dynamically under /components/[slug] and /api/[slug] for manual browsing.\n\n6. Automated Propagation of Copilot Instructions\n\n We add a `postinstall` hook to our component package that:\n - copies or appends the package-specific file `.github/copilot-instructions.md` to the target project,\n - uses unique markers to automatically replace outdated blocks during future installations,\n - handles missing or already existing files as well as idempotent updates cleanly, ensuring that every installation immediately provides the latest Copilot context for our package.\n\n7. Automate generation and propagation of Copilot instructions on package build.\n - Define `generate:agent` in `package.json` and hook into `prepare`.\n - Only include `*.md` files whose filename matches the parent directory converted to PascalCase (e.g. `custom-select` \u2192 `CustomSelect.md`), ensuring no unrelated MDs are merged.\n\n## Alternatives Considered\n\n- Rely solely on Code Search: Let Copilot use workspace search to locate docs dynamically. Rejected due to inconsistency and limited to agent mode.\n- TypeDoc-only approach: Generate API docs from TypeScript. Provides type detail but lacks usage narratives and cross-framework examples.\n- Mitosis Metadata Model: Embed JSON metadata via useMetadata and generate docs. Promising, but requires custom plugins and not widely adopted yet.\n\n## Consequences\n\n- Pros:\n - Clear separation: manual design guidance (Markdown) vs. AI context (`copilot-instructions.md` + `llms.txt` snippets).\n - Maintains single source (docs in packages/components/docs).\n - Enables Copilot to provide accurate, component-specific suggestions without manual file opening.\n - Developer site generation remains straightforward via Astro.\n - Consumers always receive the latest Copilot context without manual steps.\n - Guarantees that only the intended component documentation is merged into Copilot instructions.\n\n- Cons:\n - Requires maintaining excerpts in `copilot-instructions.md` when docs change.\n - Copilot cannot truly auto-load all linked docs; manual attachment or excerpt embedding needed for deep context.\n - Postinstall hooks may be disabled for security reasons, making it impossible to automate the copying of the copilot instructions.\n - Relies on strict naming conventions; any divergence between folder and file names will cause a component\u2019s docs to be skipped.\n', "docs/adr/adr-xx-Template.md": "# ADR-XX - XXXXX\n\n## Decision and justification\n\n## Problem description and context\n\n## General conditions and decision criteria\n\n### General conditions\n\n### Decision criteria\n\n- ...\n\n## Alternatives\n\n### A - Alternative name\n\n#### Evaluation\n\n### B - Alternative name\n\n#### Evaluation\n\n## Consequences\n\n## Links\n", "docs/chrome-devtools-integration.md": "# Chrome DevTools Integration\n\n## Overview\n\nThe DB UX Design System now includes enhanced Chrome DevTools integration via the [`vite-plugin-devtools-json`](https://www.npmjs.com/package/vite-plugin-devtools-json) plugin. This provides improved debugging capabilities during development.\n\n## What's Included\n\nThe plugin is automatically enabled in all Vite-based development environments:\n\n- React showcase (`/showcases/react-showcase/`)\n- Vue showcase (`/showcases/vue-showcase/`)\n\n## Enhanced Features\n\n### 1. DevTools JSON Generation\n\nThe plugin automatically generates a `com.chrome.devtools.json` file that provides metadata about the running application to Chrome DevTools.\n\n### 2. Better Debugging Experience\n\n- Enhanced source mapping\n- Improved component inspection\n- Better performance profiling\n- More detailed error reporting\n\n## How to Use\n\n### Prerequisites\n\n- Google Chrome or Chromium-based browser\n- Chrome DevTools (built-in)\n\n### Steps\n\n1. Start any Vite development server:\n\n ```bash\n # React showcase\n cd showcases/react-showcase && npm run dev\n\n # Vue showcase\n cd showcases/vue-showcase && npm run dev\n ```\n\n2. Open Chrome DevTools (F12)\n\n3. The enhanced debugging features will be automatically available in:\n - **Sources** tab - Better source mapping\n - **Elements** tab - Enhanced component inspection\n - **Performance** tab - More detailed profiling\n - **Console** tab - Improved error reporting\n\n### Verifying the Integration\n\nWhen the development server starts, you should see the Vite server output without any plugin errors. The DevTools JSON file is generated automatically and served by the development server.\n\n## Development Workflow\n\n### Component Development\n\n- Use the **Elements** tab to inspect component structures\n- Leverage enhanced source maps for debugging\n- Utilize improved error reporting in the **Console**\n\n### Performance Analysis\n\n- Use the **Performance** tab for detailed profiling\n- Monitor component rendering performance\n- Analyze bundle loading characteristics\n\n### Source Code Navigation\n\n- Enhanced source mapping makes debugging easier\n- Better stack traces for error resolution\n- Improved breakpoint debugging experience\n\n## Configuration\n\nThe plugin is configured with default settings in all Vite configurations:\n\n```typescript\nimport devtoolsJson from \"vite-plugin-devtools-json\";\n\n// In vite.config.ts\nplugins: [\n // ... other plugins\n devtoolsJson() // Enable Chrome DevTools JSON generation\n];\n```\n\n## Browser Compatibility\n\n- \u2705 Google Chrome (recommended)\n- \u2705 Microsoft Edge (Chromium-based)\n- \u2705 Opera (Chromium-based)\n- \u274C Firefox (limited support)\n- \u274C Safari (not supported)\n\n## Troubleshooting\n\n### Plugin Not Loading\n\nIf you see errors related to the DevTools plugin:\n\n1. Ensure you're using a Chromium-based browser\n2. Clear browser cache and restart the development server\n3. Check console for specific error messages\n\n### Missing DevTools Features\n\nIf enhanced features aren't visible:\n\n1. Verify the development server started without errors\n2. Open DevTools before navigating to the application\n3. Refresh the page with DevTools open\n\n## Production Impact\n\nThe `vite-plugin-devtools-json` only affects development builds. Production builds are not impacted:\n\n- No additional bundle size\n- No runtime performance impact\n- No security concerns\n\n## More Information\n\nFor detailed information about the plugin, visit:\n\n- [Plugin Repository](https://github.com/ChromeDevTools/vite-plugin-devtools-json)\n- [Chrome DevTools Documentation](https://developer.chrome.com/docs/devtools/)\n", "docs/conventions.md": "## Git commits conventions\n\nWe're using [husky git hooks](https://www.npmjs.com/husky) in combination with [commitlint](https://www.npmjs.com/package/@commitlint/cli) according to <https://commitlint.js.org/concepts/commit-conventions.html#concept-commit-conventions>:\n\n```text\ntype(scope?): subject\nbody?\nfooter?\n```\n\n[Type must be one of the following](https://commitlint.js.org/reference/rules.html#type-enum):\n\n- build\n- chore\n- ci\n- docs\n- feat\n- fix\n- perf\n- refactor\n- revert\n- style\n- test\n\nIf you'd like to test your commit message previous to using it, you could test it on the command line:\n\n```shell\necho 'foo: bar' | commitlint\n```\n\n## Code conventions\n\nThe general code conventions are guaranteed by the following tools.\n\n### Through configuration files: `.editorconfig` for IDEs and `.gitattributes` for git checkins\n\nBoth the [`.editorconfig`](https://editorconfig.org/) and [`.gitattributes`](https://dev.to/deadlybyte/please-add-gitattributes-to-your-git-repository-1jld) ensure a consistent code structure and conventions through their configurations.\n\n### prettier\n\nThe [prettier](https://github.com/db-ui/core/blob/main/docs/adr/code_style_formatter-prettier.adoc) tool provides a general code prettifying.\n\n## Linting\n\n### xo\n\nThe [xo](https://github.com/db-ui/core/blob/main/docs/adr/linting-xo.adoc) tool provides a general code linting mechanism.\n\n### yaml files via yamllint\n\n- [yamllint.readthedocs.io](https://yamllint.readthedocs.io/)\n\nThe [prettier](https://github.com/db-ui/core/blob/main/docs/adr/code_style_formatter-prettier.adoc) tool provides a general code prettifying.\n\n### markdown files via markdownlint\n\n- [github.com/markdownlint/markdownlint](https://github.com/markdownlint/markdownlint/)\n", "docs/definition-of-done-pr.md": '# Definition of done for Pull Requests\n\n## General\n\n- Depending on the necessary code changes for consuming packages, you may need to add a new file or include entries for the next release in the [`/docs/migration`](https://github.com/db-ux-design-system/core-web/tree/main/docs/migration) folder.\n- Please perform a final lookup of all of your changes, for example by checking the "Files changed" tab of your pull request on GitHub. This final review might lead to some findings on outstanding work, missing TODOs, `console.log` leftovers or other issues.\n', "docs/development.md": "## Development\n\n### Start developing\n\nYou'll need to insert the environment variables as described within the package [`@db-ux/db-theme`](https://www.npmjs.com/package/@db-ux/db-theme) initially.\n\nAfterwards run the following commands:\n\n```shell\nnpm install\nnpm run build\nnpm run start\n```\n\nPlease mind the [conventions for git commits](/docs/conventions.md#user-content-git-commits-conventions).\n\n### Versions\n\nAll versions in the `package.json` files are set to `0.0.0`. These are updated during the CI/CD release process.\n\n### Tests\n\nTODO: Elaborate on testing setup\n\n#### Component Tests\n\n##### Visual regression tests\n\nPlaywright is used to create and compare screenshots of each individual component.\n\n###### Pipeline generated images\n\nOn every fail of the visual regression tests in the Default pipeline, we're regenerating the snapshots as a `snapshot-*`-artifact. Please download these ones from the \"Summary\" page and commit the updated screenshots with `npm run commit:updated-snapshots` command from project root.\n\n###### Manual update\n\nTo update screenshots, simply run the following command (ensure Docker is installed and available in your shell):\n\n```shell\nnpm run regenerate:screenshots\n```\n\nIf you want to generate the screenshots manually, do the following:\n\n```shell\nnpm run build\n\n# unix\ndocker run --rm --network host --volume $(pwd):/work/ --workdir /work/ --interactive --tty mcr.microsoft.com/playwright:v1.51.1-focal /bin/bash\n\n# windows - allow file sharing (windows pop up)\ndocker run --rm --network host --volume ${PWD}:/work/ --workdir /work/ --interactive --tty mcr.microsoft.com/playwright:v1.51.1-focal /bin/bash\n\nnpm install\n\ncd output/${frameworkFolder} (replace ${frameworkFolder} with the appropriate folder name)\n\nnpx playwright test --update-snapshots\n```\n\nYou can regenerate showcase snapshots directly without docker-compose using:\n\n- `npm run regenerate:visual-snapshots --workspace=react-showcase`\n- `npm run regenerate:aria-snapshots --workspace=react-showcase`\n", "docs/evaluations/vite-plugin-devtools-json-evaluation.md": '# Evaluation: vite-plugin-devtools-json\n\n## Overview\n\nThis document evaluates the potential usage of [`vite-plugin-devtools-json` node package](https://www.npmjs.com/package/vite-plugin-devtools-json) in the DB UX Design System `core-web` repository.\n\n## What is `vite-plugin-devtools-json` node package?\n\n`vite-plugin-devtools-json` is a Vite plugin that generates a `com.chrome.devtools.json` file on the fly in the development server. This file is used by Chrome DevTools to provide enhanced debugging capabilities for web applications.\n\n**Key Details:**\n\n- Version: 1.0.0 (published August 13, 2025)\n- Maintainer: google-wombot (Google)\n- Repository: <https://github.com/ChromeDevTools/vite-plugin-devtools-json>\n- License: MIT\n- Dependencies: uuid ^11.1.0\n\n## Purpose of `com.chrome.devtools.json` file / "endpoint"\n\nThe `com.chrome.devtools.json` file is a metadata file that:\n\n1. Enables Chrome DevTools to discover and connect to debugging targets\n2. Provides additional debugging information about the running application\n3. Facilitates better integration with Chrome DevTools features\n4. Supports advanced debugging scenarios for complex web applications\n\n## Current Vite Usage in Repository\n\nThe repository currently uses Vite in several locations:\n\n### Showcases\n\n- **React Showcase** (`/showcases/react-showcase/vite.config.ts`)\n - Uses `@vitejs/plugin-react`\n - Builds to `build-showcases/react-showcase`\n - Enables CSS dev source maps\n\n- **Vue Showcase** (`/showcases/vue-showcase/vite.config.ts`)\n - Uses `@vitejs/plugin-vue`\n - Builds to `build-showcases/vue-showcase`\n - Enables CSS dev source maps\n\n## Evaluation Criteria\n\n### 1. Development Experience Benefits\n\n**Potential Benefits:**\n\n- Enhanced debugging capabilities during development\n- Better Chrome DevTools integration\n- Improved developer experience for component debugging\n- Automatic generation of DevTools metadata\n\n**Assessment:** \u2705 **Positive Impact**\n\n- Design system developers would benefit from enhanced debugging\n- Component development and testing would be improved\n- No performance impact on production builds\n\n### 2. Integration Complexity\n\n**Current Setup:**\n\n- Multiple Vite configurations already exist\n- Simple plugin architecture in place\n- Development-only concern (no production impact)\n\n**Implementation Effort:**\n\n- Low complexity - simple plugin addition\n- Minimal configuration required\n- No breaking changes to existing setup\n\n**Assessment:** \u2705 **Low Complexity**\n\n### 3. Maintenance Overhead\n\n**Considerations:**\n\n- Plugin is maintained by Google\n- Recent release (August 2025)\n- Single dependency (uuid)\n- MIT license\n\n**Assessment:** \u2705 **Low Maintenance**\n\n### 4. Use Case Alignment\n\n**Repository Context:**\n\n- Design system with multiple framework showcases\n- Component library development\n- Developer tools and debugging are important\n- Active development with multiple contributors\n\n**Assessment:** \u2705 **Good Alignment**\n\n## Recommendation\n\n### \u2705 **RECOMMENDED for Implementation**\n\n**Rationale:**\n\n1. **Low Risk:** Development-only plugin with no production impact\n2. **High Value:** Improves debugging experience for design system development\n3. **Easy Implementation:** Simple plugin addition to existing Vite configs\n4. **Google Maintained:** Reliable source and maintenance\n5. **No Breaking Changes:** Additive enhancement only\n\n### Implementation Plan\n\n#### Phase 1: Test Integration\n\n1. Add plugin to React showcase for testing\n2. Verify DevTools integration works as expected\n3. Document any benefits observed\n\n#### Phase 2: Full Rollout\n\n1. Add to all Vite configurations if Phase 1 is successful:\n - React showcase\n - Vue showcase\n2. Update documentation with DevTools usage guidelines\n\n#### Phase 3: Documentation\n\n1. Create developer guide for using enhanced DevTools features\n2. Add to development workflow documentation\n\n## Proposed Implementation\n\n### React Showcase Configuration\n\n```typescript\nimport react from "@vitejs/plugin-react";\nimport devtoolsJson from "vite-plugin-devtools-json";\nimport { defineConfig } from "vite";\n\nexport default defineConfig({\n base: `/react-showcase/`,\n plugins: [\n react(),\n devtoolsJson() // Add DevTools JSON generation\n ],\n build: {\n outDir: "../../build-showcases/react-showcase",\n emptyOutDir: true\n },\n define: {\n process\n },\n css: {\n devSourcemap: true\n }\n});\n```\n\n### Vue Showcase Configuration\n\n```typescript\nimport vue from "@vitejs/plugin-vue";\nimport devtoolsJson from "vite-plugin-devtools-json";\nimport { defineConfig } from "vite";\n\nexport default defineConfig({\n base: `/vue-showcase/`,\n plugins: [\n vue(),\n devtoolsJson() // Add DevTools JSON generation\n ],\n build: {\n outDir: "../../build-showcases/vue-showcase",\n emptyOutDir: true\n },\n css: {\n devSourcemap: true\n }\n});\n```\n\n## Conclusion\n\nThe `vite-plugin-devtools-json` plugin is a valuable addition to the DB UX Design System development workflow. It provides enhanced debugging capabilities with minimal implementation effort and no production impact. The plugin aligns well with the repository\'s focus on developer experience and component development.\n\n**Next Steps:**\n\n1. Install the plugin as a dev dependency\n2. Implement in React showcase for testing\n3. Validate enhanced DevTools functionality\n4. Roll out to other Vite configurations if successful\n', "docs/how-to-develop-a-component.md": '# How to develop a component\n\n## Generate all required files\n\n1. Run `npm run generate:component` in a terminal.\n\n2. Enter the name of your new component (e.g. my-awesome-component) and answer all prompts with "yes".\n\n3. The generation process will generate files mainly in these directories:\n\n- `packages/components`\n- `showcases`\n\n## Start developing\n\n- Your main work for the component will be inside `packages/components/src/components/my-awesome-component`.\n\n- To start developing your component, run `npm run dev`, which will present you with several options to choose from. When you begin "scribbling" (html+scss) with a component you can select `plain-html`. _Advanced users_ can skip this step and develop directly for a specific framework (HTML, SCSS, and TypeScript); see [Test Frameworks with Showcases](#test-frameworks-with-showcases).\n\n### Styling with SCSS\n\nStarting with `packages/components/src/components/my-awesome-component/my-awesome-component.scss`, there are a few important points to note:\n\n1. The most important dependency are the `variables` included via `@use "@db-ux/core-foundations/build/styles/variables";`. They enable you to use e.g. `$db-spacing-fixed-md` for paddings, margins etc.\n2. A lot of times you have to force another `font-size` / `line-height`, you can do it with `@use "@db-ux/core-foundations/build/styles/density/font;` and the corresponding placeholder extend: `@extend %db-overwrite-font-size-sm;`.\n3. Some components have an \'adaptive\' styling. We exclude it in an own file `@use "@db-ux/core-components/build/styles/internal/component";` so you might use this dependency. As a reference look at another component e.g. [`packages/components/src/components/button/button.scss`](../packages/components/src/components/button/button.scss).\n4. If you have to set a specific color (informational, warning, etc.) directly you can use `@use "@db-ux/core-foundations/build/styles/colors";`. You can take a look at the `notification` component for an example `packages/components/src/components/notification/notification.scss` you might use the `@each` to reduce the amount of code for color-variants.\n5. To set a fixed icon you might use `@use "@db-ux/core-foundations/build/styles/icons/icon-helpers" as icons;` as dependency and e.g. `@include icons.icon("arrow_forward", "after");`. For a dynamic icon you could prefer integrating it in HTML code with the `data-icon` attribute.\n\n### Component structure with HTML\n\nIn addition to the `SCSS`, you need to modify the HTML code for your component. If you start with `plain-html`, you can test your component using `packages/components/src/components/my-awesome-component/index.html`; _Advanced_ users can directly modify the `JSX` in `packages/components/src/components/my-awesome-component/my-awesome-component.lite.tsx`.\n\nThere are some things you have to know:\n\n1. There are some reserved `data-*` attributes. For example `data-icon="xxx"` or `data-icon-trailing="xxx"` which will set an icon as `::before` / `::after` contents.\n2. Moreover, there are some `data-*` attributes with the same meaning which we try to align across all components. For example `data-width` should be always `auto` or `full-width` to have the same possible options. We\'ve additionally summarized those by providing models / types for these. For a closer look on this ask the Design Team for the glossary.\n3. Try to use native HTML tags. For example if you have something like an Accordion use `<details><summary>`, so you would reduce the amount of custom JS/TS code for the components.\n\n### Define the API in `model.ts`\n\nIf you\'re happy with the styling and your HTML code, the next step is to define all possible properties for the component. Update the `packages/components/src/components/my-awesome-component/model.ts` to include properties and/or states for your component. Many properties are already predefined in `packages/components/src/shared/model.ts`. To include them, import the file as follows:\n\n```ts\nimport { WidthProps } from \'../../shared/model\';\n\nexport type DBMyAwesomeComponentProps =\n DBMyAwesomeComponentDefaultProps &\n WidthProps;\n\n...\n```\n\n### Code the \'real\' Component\n\nWe use [Mitosis](https://github.com/BuilderIO/Mitosis/tree/main/docs) to develop our components for all kinds of frameworks. The component will be placed in `packages/components/src/components/my-awesome-component/my-awesome-component.lite.tsx`. You can add your HTML code here inside the `return`. Afterwards, map all `data-*` attributes to the corresponding properties defined in `model.ts`. Check out the existing components to get an idea of how to develop a new component.\n\n### Good to know\n\n1. You cannot use functions directly in a Mitosis component. A function has to be inside the `state`. So add your function to the `model.ts` `DBMyAwesomeComponentDefaultState`. Then you can define your component inside the `.tsx` file and use it in the `jsx` with `state.myAwesomeFunction()`.\n2. Try to enable multiple ways of data-binding: For example in `select` you are able to pass in a list of `<option>` via the `props.children` similar to standard HTML composition, but we also give the developers the possibility to pass in a stripped down option list via another property: `options?: DBSelectOptionType[]`. We populate this with the internal `<For>` from Mitosis.\n Why do we do this? We have multiple frameworks and all behave differently. With multiple ways of data-binding we try to provide a JS framework native experience as closely as we can.\n3. Try to parameterize a lot: For example if your component includes an icon button you should give it a text for accessibility. You should provide a default text, so it can\'t be empty, but you should also let the user change it with a property e.g. `iconButtonText`.\n4. To enable some native functionalities for Vue and Angular (`v-model` and `[(ng-model)]`) you might need to add some extra code to your component. At the generation process you might select `formValue` anyhow, but otherwise take a look at the `input` to see what you need to add to make this work.\n5. Angular can be challenging; here are some issues to be aware of:\n 1. Angular generates custom HTML tags as wrappers, which may affect your `CSS` selectors. For example if we have a button inside our component and we try to change the styling with `.db-button: {xxx:abc;}` it would not add the styling to the button. As a workaround you should write `.db-button, .db-button > button: {xxx:abc;}` to cover Angular as well:\n\n ```html\n <db-my-awesome-component>\n <div>\n My Awesome Component\n <db-button>\n <!-- Styling would be here -->\n <button>Icon Button</button>\n <!-- not here -->\n </db-button>\n </div>\n </db-my-awesome-component>\n ```\n\n 2. You cannot use multiple slots with the same name. In other frameworks you can use the `<Slot name="bla">` multiple times like this `<div class="my-awesome-component"><Slot name="bla"><Slot name="bla"></div>` but in Angular only the last one would be shown in the DOM. As a workaround you have to create a `Directive`. We automate this via the `packages/components/scripts/post-build/components.js` as an example look at the `header` to see how it works.\n\n## Test Frameworks with Showcases\n\nOur goal is to support at least the three major frameworks (Angular, React, Vue) used at Deutsche Bahn, so you should test your component in every framework. To have the same testing possibilities we generate `showcases/shared/my-awesome-component.json`. This file is used by every framework to pass in the same properties. You should add the same blocks you see in the designs to this file.\n\nAfterwards you need to enable those properties inside all frameworks.\n\n### Angular\n\nGo to `showcases/angular-showcase/src/app/components/my-awesome-component` and update the properties inside the `my-awesome-component.html` with `exampleProps.xxx`. If you need some additional `JS` logic you have to add it to the `.ts` file. Again check out some existing component to get a feeling for this.\n\nMaybe you need to change the navigation to see the component: `showcases/angular-showcase/src/app/utils/navigation-item.ts`\n\n### React\n\nGo to `showcases/react-showcase/src/components/my-awesome-component/index.tsx` and update the properties inside the `getMyAwesomeComponent` function and inside the `tsx` component. Again check out some existing component to get a feeling for this.\n\nMaybe you need to change the navigation to see the component: `showcases/react-showcase/src/utils/navigation-item.tsx`\n\n### Vue\n\nGo to `showcases/vue-showcase/src/components/my-awesome-component/MyAwesomeComponent.vue` and update the properties inside the `DBMyAwesomeComponent` with `exampleProps.xxx`. Again check out some existing component to get a feeling for this.\n\nMaybe you need to change the navigation to see the component: `showcases/vue-showcase/src/utils/navigation-items.ts`\n\n### Patternhub\n\nTo show the component on GitHub pages we use another showcase. After you generated the component you need to add your component to the correct sub-item inside `showcases/patternhub/data/routes.ts`.\n\n## Write Tests for Quality Assurance\n\nWe have multiple tests you should update:\n\n1. Component Test: `packages/components/src/components/my-awesome-component/my-awesome-component.spec.tsx`. Just test all attributes here with screenshot tests and accessibility testing.\n2. Showcase Test: `showcases/e2e/my-awesome-component/showcase-my-awesome-component.spec.ts`. Test the styling in a specific framework here and also the functionality/events.\n\n## Manual audit conducted by accessibility experts\n\nAfter creating a component and writing all test, we need some manually third party accessibility review to prove that the component is stable. This process is internal and will be handled by a team specialized in accessibility testing.\nDuring this process you should track the progress of this manual test inside `showcases/shared/_accessibility-review.json`.\nAdd a new entry like this:\n\n```json\n {\n "name": "button",\n "status": "REVIEW",\n "date": "2023-11-23"\n },\n```\n\nYou should change the `date` prop when the first manual test starts or when it gets any update.\n\nThe `status` can be:\n\n- `REVIEW`, if the manual accessibility review should happen\n- `PROGRESS`, if there are any open issues after the test\n- `DONE`, if the component passed the accessibility review\n', "docs/how-to-test-with-db-ux-components.md": '# How to Test with DB UX Components\n\nThis guide provides recommendations for testing applications that use DB UX Design System components. Since different frameworks have different testing approaches, we\'ve organized this guide by framework.\n\n## Table of Contents\n\n- [General Testing Principles](#general-testing-principles)\n- [React Testing](#react-testing)\n- [Vue Testing](#vue-testing)\n- [Angular Testing](#angular-testing)\n- [Stencil/Web Components Testing](#stencilweb-components-testing)\n- [Common Testing Scenarios](#common-testing-scenarios)\n- [Troubleshooting](#troubleshooting)\n\n## General Testing Principles\n\n### When Testing Components vs. Applications\n\nThis guide focuses on testing **your applications** that use DB UX components, not testing the components themselves. For component development testing, see [packages/components/test/README.md](../packages/components/test/README.md).\n\n### Global Setup Considerations\n\nWhen testing applications with DB UX components, you typically need to:\n\n1. **Import CSS styles** - Components require proper styling to function correctly\n2. **Set up component libraries** - Import the framework-specific component packages\n3. **Configure test environments** - Ensure proper DOM environments for component rendering\n4. **Handle icons and assets** - Mock or provide icon assets if needed\n\n---\n\n## React Testing\n\n### Package Installation\n\n```bash\nnpm install @db-ux/react-core-components @db-ux/core-foundations\n```\n\n### Test Setup with React Testing Library\n\n#### Global Test Setup (`setupTests.ts`)\n\n```typescript\nimport "@testing-library/jest-dom";\n// Import DB UX styles\nimport "@db-ux/core-components/build/styles/rollup.css";\n\n// Optional: Mock DB UX icons globally if not using real assets\njest.mock("@db-ux/core-foundations/build/styles/icons", () => ({}));\n```\n\n#### Component Testing Example\n\n```tsx\nimport { render, screen, fireEvent } from "@testing-library/react";\nimport { DBButton, DBInput } from "@db-ux/react-core-components";\nimport MyComponent from "./MyComponent";\n\ndescribe("MyComponent with DB UX components", () => {\n test("should render button and handle click", () => {\n const handleClick = jest.fn();\n\n render(\n <DBButton onClick={handleClick} variant="brand">\n Click me\n </DBButton>\n );\n\n const button = screen.getByRole("button", { name: /click me/i });\n expect(button).toBeInTheDocument();\n\n fireEvent.click(button);\n expect(handleClick).toHaveBeenCalledTimes(1);\n });\n\n test("should type in DB input field", () => {\n const handleChange = jest.fn();\n\n render(\n <DBInput\n label="Test Input"\n value=""\n onChange={handleChange}\n data-testid="test-input"\n />\n );\n\n const input = screen.getByTestId("test-input");\n fireEvent.change(input, { target: { value: "test value" } });\n\n expect(handleChange).toHaveBeenCalledWith(\n expect.objectContaining({\n target: expect.objectContaining({\n value: "test value"\n })\n })\n );\n });\n});\n```\n\n#### Mocking DB UX Components\n\nFor unit tests where you want to mock DB UX components:\n\n```tsx\n// __mocks__/@db-ux/react-core-components.tsx\nexport const DBButton = jest.fn(({ children, onClick, ...props }) => (\n <button onClick={onClick} {...props}>\n {children}\n </button>\n));\n\nexport const DBInput = jest.fn((props) => <input {...props} />);\n```\n\n#### Playwright Testing with React\n\n```typescript\nimport { test, expect } from \'@playwright/experimental-ct-react\';\nimport { DBButton } from \'@db-ux/react-core-components\';\n\ntest(\'DBButton interaction\', async ({ mount }) => {\n let clicked = false;\n\n const component = await mount(\n <DBButton onClick={() => clicked = true}>\n Test Button\n </DBButton>\n );\n\n await component.click();\n expect(clicked).toBe(true);\n});\n```\n\n---\n\n## Vue Testing\n\n### Package Installation\n\n```bash\nnpm install @db-ux/v-core-components @db-ux/core-foundations\n```\n\n### Test Setup with Vue Test Utils\n\n#### Global Test Setup (`vitest.config.ts` or test setup file)\n\n```typescript\nimport { createApp } from "vue";\nimport { config } from "@vue/test-utils";\n\n// Import DB UX styles\nimport "@db-ux/core-components/build/styles/rollup.css";\n\n// Global component registration (optional)\nimport { DBButton, DBInput } from "@db-ux/v-core-components";\n\nconfig.global.components = {\n DBButton,\n DBInput\n};\n```\n\n#### Component Testing Example\n\n```typescript\nimport { mount } from "@vue/test-utils";\nimport { DBButton, DBInput } from "@db-ux/v-core-components";\nimport MyComponent from "./MyComponent.vue";\n\ndescribe("MyComponent with DB UX components", () => {\n test("should render button and handle click", async () => {\n const wrapper = mount(DBButton, {\n props: {\n variant: "brand"\n },\n slots: {\n default: "Click me"\n }\n });\n\n expect(wrapper.text()).toContain("Click me");\n\n await wrapper.trigger("click");\n expect(wrapper.emitted("click")).toHaveLength(1);\n });\n\n test("should handle input changes", async () => {\n const wrapper = mount(DBInput, {\n props: {\n label: "Test Input",\n modelValue: ""\n }\n });\n\n const input = wrapper.find("input");\n await input.setValue("test value");\n\n expect(wrapper.emitted("update:modelValue")).toEqual([["test value"]]);\n });\n});\n```\n\n#### Mocking DB UX Components in Vue\n\n```typescript\n// Create mock components\nconst mockDBButton = {\n name: "DBButton",\n template: "<button @click=\\"$emit(\'click\', $event)\\"><slot /></button>",\n emits: ["click"]\n};\n\nconst mockDBInput = {\n name: "DBInput",\n template:\n "<input @input=\\"$emit(\'update:modelValue\', $event.target.value)\\" />",\n emits: ["update:modelValue"]\n};\n\n// Use in tests\nconst wrapper = mount(MyComponent, {\n global: {\n components: {\n DBButton: mockDBButton,\n DBInput: mockDBInput\n }\n }\n});\n```\n\n---\n\n## Angular Testing\n\n### Package Installation\n\n```bash\nnpm install @db-ux/ngx-core-components @db-ux/core-foundations\n```\n\n### Test Setup with Angular Testing Utilities\n\n#### Global Test Setup (`test.ts` or `karma.conf.js`)\n\n```typescript\n// Import DB UX styles in your angular.json or component styles\n// Or in src/styles.css:\n// @import \'@db-ux/core-components/build/styles/rollup.css\';\n```\n\n#### Module Setup for Testing\n\n```typescript\nimport { ComponentFixture, TestBed } from "@angular/core/testing";\nimport { DBButton, DBInput } from "@db-ux/ngx-core-components";\nimport { MyComponent } from "./my-component.component";\n\ndescribe("MyComponent", () => {\n let component: MyComponent;\n let fixture: ComponentFixture<MyComponent>;\n\n beforeEach(async () => {\n await TestBed.configureTestingModule({\n imports: [DBButton, DBInput, MyComponent] // Using standalone components\n }).compileComponents();\n\n fixture = TestBed.createComponent(MyComponent);\n component = fixture.componentInstance;\n fixture.detectChanges();\n });\n\n test("should create", () => {\n expect(component).toBeTruthy();\n });\n});\n```\n\n#### Component Testing Example\n\n```typescript\nimport { ComponentFixture, TestBed } from "@angular/core/testing";\nimport { By } from "@angular/platform-browser";\nimport { DBButton } from "@db-ux/ngx-core-components";\n\ndescribe("DBButton Integration", () => {\n let component: TestHostComponent;\n let fixture: ComponentFixture<TestHostComponent>;\n\n @Component({\n template: `\n <db-button\n [variant]="variant"\n (click)="handleClick($event)"\n data-testid="test-button"\n >\n Test Button\n </db-button>\n `,\n standalone: true,\n imports: [DBButton]\n })\n class TestHostComponent {\n variant = "brand";\n clickCount = 0;\n\n handleClick() {\n this.clickCount++;\n }\n }\n\n beforeEach(async () => {\n await TestBed.configureTestingModule({\n imports: [TestHostComponent]\n }).compileComponents();\n\n fixture = TestBed.createComponent(TestHostComponent);\n component = fixture.componentInstance;\n fixture.detectChanges();\n });\n\n test("should handle button click", () => {\n const button = fixture.debugElement.query(\n By.css(\'[data-testid="test-button"]\')\n );\n\n button.triggerEventHandler("click", null);\n\n expect(component.clickCount).toBe(1);\n });\n});\n```\n\n#### Mocking DB UX Components in Angular\n\n```typescript\n// Create mock components\n@Component({\n selector: "db-button",\n template:\n \'<button (click)="click.emit($event)"><ng-content></ng-content></button>\',\n standalone: true\n})\nclass MockDBButton {\n @Input() variant: string = "";\n @Output() click = new EventEmitter();\n}\n\n// Use in tests\nawait TestBed.configureTestingModule({\n imports: [MockDBButton] // Instead of real DBButton\n}).compileComponents();\n```\n\n---\n\n## Stencil/Web Components Testing\n\n### Package Installation\n\n```bash\nnpm install @db-ux/wc-core-components @db-ux/core-foundations\n```\n\n### Test Setup\n\n```typescript\nimport { newSpecPage } from "@stencil/core/testing";\nimport "@db-ux/core-components/build/styles/rollup.css";\n\n// Define custom elements if needed\nimport { defineCustomElements } from "@db-ux/wc-core-components/dist/loader/index.js";\ndefineCustomElements();\n```\n\n#### Component Testing Example\n\n```typescript\ndescribe("Web Components Integration", () => {\n test("should render db-button", async () => {\n const page = await newSpecPage({\n html: `<db-button variant="brand">Test Button</db-button>`\n });\n\n expect(page.root).toEqualHtml(`\n <db-button variant="brand">\n <button class="db-button" data-variant="brand">\n Test Button\n </button>\n </db-button>\n `);\n });\n});\n```\n\n---\n\n## Common Testing Scenarios\n\n### Testing Form Interactions\n\n#### React Example\n\n```tsx\ntest("form submission with DB components", async () => {\n const handleSubmit = jest.fn();\n\n render(\n <form onSubmit={handleSubmit}>\n <DBInput\n label="Email"\n type="email"\n data-testid="email-input"\n required\n />\n <DBButton type="submit">Submit</DBButton>\n </form>\n );\n\n const emailInput = screen.getByTestId("email-input");\n const submitButton = screen.getByRole("button", { name: /submit/i });\n\n fireEvent.change(emailInput, { target: { value: "test@example.com" } });\n fireEvent.click(submitButton);\n\n expect(handleSubmit).toHaveBeenCalled();\n});\n```\n\n### Testing Navigation Components\n\n#### Vue Example\n\n```typescript\ntest("navigation item click", async () => {\n const wrapper = mount(DBNavigation, {\n props: {\n items: [\n { href: "/home", label: "Home" },\n { href: "/about", label: "About" }\n ]\n }\n });\n\n const homeLink = wrapper.find(\'[href="/home"]\');\n await homeLink.trigger("click");\n\n expect(wrapper.emitted("navigate")).toBeTruthy();\n});\n```\n\n### Testing Accessibility\n\n#### Playwright Example\n\n```typescript\nimport { test, expect } from "@playwright/test";\nimport AxeBuilder from "@axe-core/playwright";\n\ntest("accessibility with DB components", async ({ page }) => {\n await page.goto("/your-page-with-db-components");\n\n const accessibilityScanResults = await new AxeBuilder({ page }).analyze();\n\n expect(accessibilityScanResults.violations).toEqual([]);\n});\n```\n\n### Testing Component State Changes\n\n#### Angular Example\n\n```typescript\ntest("toggle component state", async () => {\n const fixture = TestBed.createComponent(TestHostComponent);\n const component = fixture.componentInstance;\n\n // Test initial state\n expect(component.isToggled).toBe(false);\n\n // Trigger toggle\n const toggleButton = fixture.debugElement.query(By.css("db-button"));\n toggleButton.triggerEventHandler("click", null);\n fixture.detectChanges();\n\n expect(component.isToggled).toBe(true);\n});\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues and Solutions\n\n#### 1. Styling Issues in Tests\n\n**Problem**: Components don\'t render with proper styles\n\n**Solution**: Make sure to import CSS files in your test setup:\n\n```typescript\n// React\nimport \'@db-ux/core-components/build/styles/rollup.css\';\n\n// Vue\nimport \'@db-ux/core-components/build/styles/rollup.css\';\n\n// Angular - Add to angular.json or styles.css\n@import \'@db-ux/core-components/build/styles/rollup.css\';\n```\n\n#### 2. Icon Loading Issues\n\n**Problem**: Icons don\'t load in test environment\n\n**Solution**: Mock icon dependencies:\n\n```typescript\n// Jest\njest.mock("@db-ux/core-foundations/build/styles/icons", () => ({}));\n\n// Or provide a test icon set\n```\n\n#### 3. Custom Element Registration (Web Components)\n\n**Problem**: Custom elements not recognized\n\n**Solution**: Define custom elements in test setup:\n\n```typescript\nimport { defineCustomElements } from "@db-ux/wc-core-components/dist/loader/index.js";\ndefineCustomElements();\n```\n\n#### 4. TypeScript Type Issues\n\n**Problem**: TypeScript can\'t find component types\n\n**Solution**: Install and import type definitions:\n\n```typescript\nimport type { DBButtonProps } from "@db-ux/react-core-components";\n// or\nimport type { DBButtonProps } from "@db-ux/v-core-components";\n// or\nimport type { DBButtonProps } from "@db-ux/ngx-core-components";\n```\n\n#### 5. Event Handling Differences\n\n**Problem**: Events work differently across frameworks\n\n**React**: Use `onClick`, `onChange`, etc.\n\n```tsx\n<DBButton onClick={handleClick}>Button</DBButton>\n```\n\n**Vue**: Use `@click`, `@change`, etc.\n\n```vue\n<DBButton @click="handleClick">Button</DBButton>\n```\n\n**Angular**: Use `(click)`, `(change)`, etc.\n\n```html\n<db-button (click)="handleClick()">Button</db-button>\n```\n\n### Performance Considerations\n\n- **Shallow rendering**: Use shallow rendering when testing component logic without full DOM\n- **Mock heavy components**: Mock complex DB components when testing your business logic\n- **Async operations**: Always await async operations in tests\n- **Memory leaks**: Clean up event listeners and timers in test teardown\n\n### Best Practices\n\n1. **Use data-testid attributes** for reliable element selection\n2. **Test user interactions** rather than implementation details\n3. **Mock external dependencies** that aren\'t part of your component logic\n4. **Test accessibility** using tools like @axe-core/playwright\n5. **Keep tests focused** - test one behavior per test case\n6. **Use page object models** for complex interaction flows\n\nFor more information about component development and internal testing, see:\n\n- [How to develop a component](./how-to-develop-a-component.md)\n- [Component testing README](../packages/components/test/README.md)\n', "docs/migration/alpha-beta.md": '# Migration Alpha (0.0.x) \u27A1 Beta (0.1.x)\n\n## Foundations\n\n### Breaking Changes\n\n| Name | Description | Action |\n| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| \u{1F504} renamed `Tonality` to `Density` | class names and data-attributes changed from <br/>`.db-ux-#{$tonality},[data-tonality="#{$tonality}"] {` to <br/>`.db-#{density},[data-density="#{density}"] {` | search `tonality` & replace with `density` |\n| \u274C removed `opacity` tokens | we use only 1 opacity (0.4) for all components | If you use some of the tokens like `--db-opacity-sm` you might run into issues with your layout |\n| \u{1F504} updated `border` tokens | we add all shirt-sizes `3xs`-`3xl` as tokens | If you use some of the tokens like `db-border-height-sm` you might run into issues with your layout, because the values behind it changed |\n| \u{1F504} moved `_font-sizes.scss` | We moved the file to another folder to align the same structure as icons or colors. We add `css` classes, you can use them by importing `@db-ux/core-foundations/scss/fonts/classes/all.css` | If you use some placeholder like `%db-overwrite-font-size-sm` you might need to import the `_font-sizes.scss` like this: `@use "@db-ux/core-foundations/build/styles/fonts";` |\n| \u{1F504} \u2757 refactored `colors` | All colors changed. We use color-palettes to generate speaking-names (check `@db-ux/core-foundations/scss/colors/_variables.scss` to see a list of available tokens). We removed `base` color, it was the same like `neutral`. Add different background level. | 1. Replace all `base` colors with `neutral`<br/>2. If you use the color class replace `db-bg-x` with `db-x-bg-lvl-1`<br/>3. Replace `border-strong`/ `border-weak` tokens with `contrast-high`/`contrast-low` |\n| \u{1F504} renamed timing variables | renamed `$db-transition-emotional-timing` to `$db-transition-timing-emotional` / `--db-transition-emotional-timing` to `--db-transition-timing-emotional` | Replace `transition-emotional-timing` by `transition-timing-emotional` |\n\n### Internal\n\n| Name | Description | Action |\n| --------------------------------- | -------------------------------------------------------------------------------------------------------- | ------ |\n| \u274C removed `style-dictionary` | all variables will be generated in [theme-builder](https://github.com/db-ux-design-system/theme-builder) | --- |\n| \u274C removed `zeplin-styleguide.js` | we use `Figma` in the future | --- |\n\n## Components\n\n> **Note**: All components have different colors and opacities based on the changes in foundations.\n\nSome components may have different dimensions based on changes of spacing tokens.\n\nWe removed the default elevation (box-shadow) for card and some card-like components.\n\nThe prop variant (`variant="informational"`,`variant="successful"`,`variant="warning"`,`variant="critical"`) has been renamed to `semantic`.\n\nThe prop labelVariant for form-components (input, checkbox, ...) has been renamed to `variant`.\n\n| Name | Description | Action |\n| -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| \u{1F504} renamed `db-alert` to `db-notification` | renamed `alert` to `notification` and add/changed some additional properties | 1. Replace `DBAlert`, `db-alert` by `DBNotification` / `db-notification`<br/>2. `Link` was removed, add a normal `a` or `DBLink` to the `slotLink`<br/>3. `props.type` has been changed to `props.variant`<br/>4. `onClick` has been changed to `onClose` |\n| \u{1F504} renamed `db-main-navigation` to `db-navigation` | renamed `main-navigation` to `navigation` | Replace `DBMainNavigation`, `db-main-navigation` by `DBNavigation` / `db-navigation` |\n| \u{1F504} changed `db-button` variants | We renamed the variants for the button | `primary` \u27A1 `brand`<br/>`solid` \u27A1 `filled`<br/>`text` \u27A1 `ghost` |\n| \u{1F504} changed `db-card` elevation | We replaced the box-shadow elevation with bg-level | 1. `props.elevation` \u27A1 `props.elevationLevel` (1,2,3) <br/>2. `props.variant` \u27A1 `props.behaviour` <br/>3. Removed card-image |\n| \u{1F195} valid/invalid message form-components | We add additional messages for `required` form-components like `DBInput` etc. | Use `validMessage="XXX"` and `invalidMessage="XXX"` to display the required information for form-components. Otherwise you will see a default message with a `TODO: ...` |\n| \u{1F504} changed `db-link` variant | We renamed the variants for the link | `primary` \u27A1 `brand` |\n| \u274C removed `data-variant="information/critical/..."` for form-components like `input`, `select` and `textarea` | We don\'t support the colors changes anymore. Use `required`, `pattern`, `min` etc. to trigger `user-valid` for green and red components | `data-variant` changes the label variant now |\n| \u{1F504} changed `db-accordion` title | We replaced `title` with `headlinePlain` because there is already a html default `title`, which caused trouble | Rename `title` to `headlinePlain` or use the slot `headline` |\n| \u274C removed prop `areaPopup` from `db-navigation-item` | We no longer support opening sub-navigations from via prop. | There is no alternative at the moment. |\n| \u{1F504} changed `db-header` slot names | The slot names for "action" containers changed | 1. `callToAction` \u27A1 `primaryAction` <br/>2. `actionBar` \u27A1 `secondaryAction` |\n| \u{1F504} renamed `size` & `variant` in `db-section` | The properties `size` and `variant` in `db-section` were renamed to `spacing` & `width` to align it with other components | Search for every `db-section` and replace `size` with `spacing` and `variant` with `width` |\n\n### React\n\n`slot` prefix was removed for all components containing another child element, for example:\n\n```tsx\n<DBHeader slotBrand={...\n```\n\nbecomes\n\n```tsx\n<DBHeader brand={...\n```\n\nThis is related to the following properties:\n\n- `slotHeader`\n- `slotBrand`\n- `slotMetaNavigation`\n- `slotCallToAction` (`primaryAction`)\n- `slotActionBar` (`secondaryAction`)\n- `slotHeadline`\n- `slotDrawerHeader`\n- `slotSubNavigation`\n\n## Styling\n\nWe add some more information about our styling and try to generate classes and data-attributes to use in the project, based on user-preferences.\nMoreover, we add all optional styles to `db-ux-42` which may increase the size, but reduces the complexity for using the Design-System with all features.\n\nIf you encounter performance issues try to reduce your loaded styles with this [documentation](https://github.com/db-ux-design-system/core-web/blob/main/packages/components/README.md#optimize-dependencies) or by using a tool like [purgecss](https://purgecss.com/).\n', "docs/migration/db-ui-to-db-ux-dsv3.md": '# DB-UI to DB-UX Design System v3 Component Migration Guide\n\n> **Note**\n> This document provides migration guidance for DB-UI components that don\'t have direct equivalents in DB-UX Design System v3. For package name changes and general migration information, see [v0.7.x-to-v1.0.0.md](./v0.7.x-to-v1.0.0.md).\n\n## Overview\n\nDB-UX Design System v3 represents a complete rethinking of the component architecture with a focus on atomic design principles, accessibility, and modern web standards. Some DB-UI components have been redesigned, consolidated, or are planned for future releases.\n\n## Components without Direct Equivalents\n\n| Component | Status | Recommendation | Description |\n| --------------------------- | :----: | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `rea-main` | \u274C | Use `db-page` with custom layout | The `db-page` component provides basic page structure. It already includes `<main>` |\n| `rea-grid` | \u274C | Use CSS Grid or `db-stack` component | Replace with modern CSS Grid for complex layouts, or use `db-stack` for simple spacing. See [CSS Grid examples](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout) |\n| `rea-footer` | \u{1F504} | Under research - build custom for now ,Planned for Q4/2025 | Footer component is being researched. Use semantic `<footer>` element with `db-link` components and custom styling. [Research document](../research/footer.md) |\n| `elm-headline` | \u{1F501} | Use heading elements with `db-infotext`, Planned for Q4/2025 | Replace with semantic heading tags (`<h1>`, `<h2>`, etc.) styled with CSS. For subtitle functionality, combine with `db-infotext` |\n| `elm-headline` (with pulse) | \u274C | Use heading + CSS animation, Planned for Q4/2025 | Implement pulse animation using CSS animations or transitions on heading elements. Pulse animations should be used sparingly for accessibility |\n| `elm-loadingindicator` | \u{1F504} | Planned for Q4/2025 | Loading indicator component is planned. Use CSS spinners or skeleton screens temporarily. Consider accessibility with `aria-live` regions |\n| `elm-progress` | \u{1F504} | Planned for Q4/2025 | Progress component in development. Use HTML5 `<progress>` element with custom styling or build custom solution |\n| `elm-chip` | \u{1F501} | Use `db-tag` with interactive elements | Replace with `db-tag` containing `db-button`, `db-checkbox`, or `db-radio` for interactive functionality. See [tag migration guide](../../packages/components/src/components/tag/docs/Migration.md) |\n| `cmp-breadcrumb` | \u{1F504} | Planned for Q4/2025 | Breadcrumb component planned for future release. Use `db-link` components with `aria-label="Breadcrumb"` navigation wrapper |\n| `cmp-pagination` | \u{1F504} | Planned for Q4/2025 | Pagination component in development. Build custom solution with `db-button` components and proper ARIA labels |\n| `cmp-table` | \u{1F504} | Under active research | Table component being researched with comprehensive roadmap. Use semantic HTML tables with custom styling. [Research document](../research/table.md) |\n| `cmp-sidenavi` | \u{1F501} | Use `db-navigation` in `db-drawer` | Combine `db-navigation` component within `db-drawer` for side navigation functionality. Configure drawer with appropriate width and positioning |\n| `cmp-dialog` | \u{1F501} | Use `db-drawer` or custom modal, Planned for Q4/2025 | Use `db-drawer` for side panels, or build custom modal dialog with proper focus management and ARIA attributes |\n\n## Legend\n\n| Symbol | Meaning |\n| :----: | --------------------------------------------------------------------- |\n| \u{1F501} | **Available replacement** - Use suggested alternative component(s) |\n| \u{1F504} | **Planned for future** - Component in roadmap, use temporary solution |\n| \u274C | **Not planned** - Use alternative approach or build custom solution |\n| \u{1F195} | **New in DB-UX-DSv3** - Enhanced or new functionality available |\n\n## Migration Strategies\n\n### 1. Layout Components Migration\n\n#### From `rea-main` to `db-page` + Custom Layout\n\n```html\n<!-- DB-UI -->\n<div class="rea-main">\n <main>Content</main>\n</div>\n\n<!-- DB-UX-DSv3 -->\n<db-page> Content </db-page>\n```\n\n#### From `rea-grid` to CSS Grid\n\n```css\n/* DB-UI grid replacement */\n.custom-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: var(--db-spacing-fixed-md);\n}\n```\n\n### 2. Interactive Elements Migration\n\n#### From `elm-chip` to `db-tag`\n\n```html\n<!-- DB-UI -->\n<div class="elm-chip" data-variant="primary">Chip Text</div>\n\n<!-- DB-UX-DSv3 -->\n<db-tag>\n <db-button variant="ghost">Chip Text</db-button>\n</db-tag>\n```\n\n#### From `elm-headline` to Semantic Headings\n\n```html\n<!-- DB-UI -->\n<div class="elm-headline" data-size="h1">Main Title</div>\n\n<!-- DB-UX-DSv3 -->\n<h1 class="custom-headline">Main Title</h1>\n<!-- Optional subtitle -->\n<db-infotext>Subtitle text</db-infotext>\n```\n\n### 3. Navigation Migration\n\n#### From `cmp-sidenavi` to `db-navigation` + `db-drawer`\n\n```html\n<!-- DB-UX-DSv3 -->\n<db-drawer>\n <db-navigation>\n <db-navigation-item>\n <db-link href="/page1">Navigation Item 1</db-link>\n </db-navigation-item>\n <db-navigation-item>\n <db-link href="/page2">Navigation Item 2</db-link>\n </db-navigation-item>\n </db-navigation>\n</db-drawer>\n```\n\n## Accessibility Considerations\n\nWhen building custom solutions for missing components:\n\n1. **Use semantic HTML** - Always start with appropriate HTML elements\n2. **ARIA attributes** - Add proper ARIA labels, roles, and states\n3. **Keyboard navigation** - Ensure all interactive elements are keyboard accessible\n4. **Focus management** - Handle focus properly in dynamic content\n5. **Screen reader support** - Test with screen readers and provide meaningful announcements\n\n## Temporary Solutions & Best Practices\n\n### Loading States\n\n```html\n<!-- Temporary loading indicator -->\n<div class="custom-loading" aria-live="polite" aria-label="Loading content">\n <div class="spinner"></div>\n <span class="visually-hidden">Loading...</span>\n</div>\n```\n\n### Progress Indicators\n\n```html\n<!-- HTML5 progress element -->\n<progress value="70" max="100" aria-label="Upload progress: 70%">70%</progress>\n```\n\n### Breadcrumb Navigation\n\n```html\n<!-- Semantic breadcrumb structure -->\n<nav aria-label="Breadcrumb">\n <ol class="breadcrumb-list">\n <li><db-link href="/">Home</db-link></li>\n <li><db-link href="/category">Category</db-link></li>\n <li aria-current="page">Current Page</li>\n </ol>\n</nav>\n```\n\n## Getting Help\n\n- **Documentation**: [Component documentation](https://www.npmjs.com/package/@db-ux/core-components)\n- **Migration CLI**: Use `npx @db-ux/core-migration --type=v007_v100 --src=./src` for automated migration\n- **Research Updates**: Check [research documents](../research/) for component development status\n- **Community**: Join discussions about missing components in GitHub issues\n\n## Future Roadmap\n\nCheck the [project board](https://github.com/orgs/db-ux-design-system/projects/4/views/1) for current status and release planning.\n\n---\n\n_This migration guide is maintained by the DB-UX Design System team. For specific component requests or migration assistance, please open an issue on GitHub._\n', "docs/migration/v0.2.x-to-v0.3.x.md": "# Migration Beta (0.2.x) \u27A1 Beta (0.3.x)\n\nWe refactored our colors which might add some breaking changes to current projects: <https://marketingportal.extranet.deutschebahn.com/marketingportal/Design-Anwendungen/db-ux-design-system/support/migration-guides/v0-3-0>\n\n## Migration table\n\n| old | new | description |\n| ---------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------- |\n| bg-lvl-1 | bg-basic-level-1 | |\n| bg-lvl-2 | bg-basic-level-2 | |\n| bg-lvl-3 | bg-basic-level-3 | |\n| bg-transparent-full | bg-basic-transparent-full | |\n| bg-transparent-semi | bg-basic-transparent-semi | |\n| bg-transparent-hover | bg-basic-transparent-hovered | |\n| bg-transparent-pressed | bg-basic-transparent-pressed | |\n| on-bg | on-bg-basic-emphasis-100 | |\n| on-bg-weak | on-bg-basic-emphasis-90 | |\n| contrast-high | bg-inverted-contrast-high / on-bg-basic-emphasis-80 | we split this color as background color and foreground color. `\u2757 automigration might not work` |\n| contrast-low | bg-inverted-contrast-low / on-bg-basic-emphasis-70 | we split this color as background color and foreground color. `\u2757 automigration might not work` |\n| border | on-bg-basic-emphasis-60 | |\n| on-contrast | on-bg-inverted | |\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-foundations@v0.3 migration --src=./src\n```\n", "docs/migration/v0.3.x-to-v0.4.x.md": "# Migration Beta (0.3.x) \u27A1 Beta (0.4.x)\n\n## Icons\n\nWe refactored our icons which might add some breaking changes to current projects: <https://marketingportal.extranet.deutschebahn.com/marketingportal/Design-Anwendungen/db-ux-design-system/support/migration-guides/v0-3-0>\n\n### Migration table\n\n| old | new |\n| ------------------- | ------------------------- |\n| swap_vertical | arrows_vertical |\n| swap_horizontal | arrows_horizontal |\n| reload | circular_arrows |\n| volume_off | volume_silent |\n| law | paragraph_mark |\n| user | person |\n| users | persons |\n| wc_men | toilet_men |\n| wc_women | toilet_women |\n| wc | toilets |\n| filter | sliders_horizontal |\n| warning_triangle | exclamation_mark_triangle |\n| visible | eye |\n| visibility_disabled | eye_disabled |\n| flip_horizontal | arrows_horizontal |\n| flip_vertical | arrows_vertical |\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-foundations@v0.4 migration --type=icon --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace and there might be unexpected changes of similar wordings to our icon names for any other methods, or further code occurrences that don't even refer to icons.\n", "docs/migration/v0.4.x-to-v0.5.x.md": "# Migration Beta (0.4.x) \u27A1 Beta (0.5.x)\n\nNo breaking changes\n", "docs/migration/v0.5.x-to-v0.6.x.md": '# Migration Beta (0.5.x) \u27A1 Beta (0.6.x)\n\n## Icons\n\nWe removed the `.svg` icons from `@db-ux/core-foundations`. This will not affect the `woff2` files required for components. If you still need some `.svg` files you need to install [`@db-ux/core-icons`](https://www.npmjs.com/package/@db-ux/core-icons).\n\n## Components\n\nWe changed some properties for components to align with Figma properties:\n\n### Accordion-Item\n\n- `content` \u27A1\uFE0F `text`\n\n### Notification\n\n- `behaviour="closeable|permanent"` \u27A1\uFE0F `closeable="true/false"`- Defaults to `false`\n\n### Form-Components (Input, Select, Checkbox, Radio, Switch, Textarea)\n\n- `variant="hidden"` \u27A1\uFE0F `showLabel="true/false"` - Defaults to `true`\n- `customValidity` \u27A1\uFE0F `validation`\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code (except for `content` to `text` attribute on `Accordion-Item`). Use this command in your repository:\n\n```shell\nnpx @db-ux/core-migration --type=v005_v006 --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace and there might be unexpected changes of similar wordings to our icon names for any other methods, or further code occurrences that don\'t even refer to icons.\n', "docs/migration/v0.6.x-to-v0.7.x.md": "# Migration Beta (0.6.x) \u27A1 Beta (0.7.x)\n\n## Removed brand assets\n\nWe needed to remove the brand assets (font & icons) from our [`@db-ux/core-foundations`](https://www.npmjs.com/package/@db-ux/core-foundations) node package. Please follow the guidelines within [DB Marketingportal](https://marketingportal.extranet.deutschebahn.com/marketingportal/Design-Anwendungen/db-ux-design-system/resources/db-theme) on how to retrieve it either as an Inner Source package (DB internal) or to still install the node package from [npmjs.com](https://www.npmjs.com/package/@db-ux/db-theme) (DB external).\n\n## Path changes\n\nWe needed to change some path, so you would probably need to make some adaptions within your code:\n\n- Changed `@db-ux/core-foundations/build/scss/` to `@db-ux/core-foundations/build/styles/`\n- Changed `@db-ux/core-foundations/build/css/` to `@db-ux/core-foundations/build/styles/`\n- Changed `@db-ux/core-icons/` to `@db-ux/core-icons/build`\n\nAnd icon font files have been moved from `functional/fonts/` one level up to `fonts/` folder, probably you would need to copy those to your codebase as well again if you don't use a bundler.\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-migration --type=v006_v007 --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace regarding the path.\n", "docs/migration/v0.7.x-to-v1.0.0.md": '# Migration Beta (0.7.x) \u27A1 1.0.0\n\n## Packages\n\n- `@db-ui/foundations` \u27A1\uFE0F `@db-ux/core-foundations`\n- `@db-ui/components` \u27A1\uFE0F `@db-ux/core-components`\n- `@db-ui/migration` \u27A1\uFE0F `@db-ux/core-migration`\n- `@db-ui/stylelint` \u27A1\uFE0F `@db-ux/core-stylelint`\n- `@db-ui/ngx-components` \u27A1\uFE0F `@db-ux/ngx-core-components`\n- `@db-ui/react-components` \u27A1\uFE0F `@db-ux/react-core-components`\n- `@db-ui/v-components` \u27A1\uFE0F `@db-ux/v-core-components`\n- `@db-ui/web-components` \u27A1\uFE0F `@db-ux/wc-core-components`\n\n## Foundations\n\nWe update some classes and `data-`-attributes to match with the "Appearances" inside Figma:\n\n- `data-color-scheme` \u27A1\uFE0F `data-mode` - if you set a container to a fixed `dark` or `light` mode\n- `data-container-color` \u27A1\uFE0F `data-color` - if you changed an adaptive color scheme\n- \u274C `data-color="XXX-bg-basic-level-[1|2|3]"` - removed combination of background and adaptive color scheme\n\n## Components\n\nWe changed some properties for components to align with Figma properties:\n\n### Global\n\n- Renamed all `behaviour` props to `behavior`\n\n### Accordion\n\n- `behaviour="default"` \u27A1\uFE0F `behavior="divider"`\n\n### Badge\n\nWe updated the colors for the `weak` badge to match better with `strong` and the new `origin` badge.\n\n### Card\n\n- `behaviour="default"` \u27A1\uFE0F `behavior="static"`\n\n### Tabs\n\nWe updated the colors for the `weak` tag to match better with `strong` and the new `origin` tag.\n\n- `behaviour` \u27A1\uFE0F `behavior`\n\n### Tag\n\n- `behaviour` \u27A1\uFE0F `behavior`\n\n### Tooltip\n\n- `variant="\'with arrow\'|\'basic\'"` \u27A1\uFE0F `showArrow="true|false"` - Defaults to `true`\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-migration --type=v007_v100 --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace and there might be unexpected changes of similar wordings to our properties for any other methods, or further code occurrences that don\'t even refer to properties.\n\n## Complete DB-UI Component Migration Guide\n\nFor a comprehensive overview of all DB-UI components and their migration status in DB-UX Design System v3, including components that don\'t have direct equivalents, see the [DB-UI to DB-UX Design System v3 Component Migration Guide](./db-ui-to-db-ux-dsv3.md).\n', "docs/migration/v1.x.x-to-v2.0.0.md": "# Migration (1.x.x) \u27A1 2.0.0\n\n## Tag and Batch components\n\nWe removed the emphasis `origin` from the Tag and Batch components.\nAdditionally, we now use the `bg-vibrant` and `on-bg-vibrant` colors for the emphasis `strong` of the Tag and Batch components.\n\n## Angular\n\n> **Note:** We upgrade the components to use [`signals`](https://angular.dev/guide/signals). This requires the latest version of Angular (18.0.0 or higher). If you are using an older version, please upgrade to the latest versions (18, 19, or 20) of Angular.\n\n### Align angular events\n\nWe removed the `on` prefix for every event in Angular to match the best practices of Angular. The following events have been changed:\n\n- `onClick` \u2794 `click`\n- `onChange` \u2794 `change`\n- `onFocus` \u2794 `focus`\n- `onBlur` \u2794 `blur`\n- `onInput` \u2794 `input`\n- `onRemove` \u2794 `remove`\n- `onSelect` \u2794 `select`\n- `onToggle` \u2794 `toggle`\n- `onClose` \u2794 `close`\n- `onTabSelect` \u2794 `tabSelect`\n- `onIndexChange` \u2794 `indexChange`\n\n## Foundation\n\n### Web Fonts\n\nWe've replaced DB Screen fonts by their successor, DB Neo Screen. If you've copied over those fonts out of the DB theme package to your project manually, you would need to do this again for these new files.\n\n### Design Tokens\n\n- Removed `--db-adaptive-on-origin-hovered`\n- Removed `--db-adaptive-on-origin-pressed`\n- Removed `--db-adaptive-on-bg-basic-emphasis-60-hovered`\n- Removed `--db-adaptive-on-bg-basic-emphasis-60-pressed`\n- Removed `--db-adaptive-on-bg-basic-emphasis-50-hovered`\n- Removed `--db-adaptive-on-bg-basic-emphasis-50-pressed`\n\n#### Fonts\n\n- Removed all `db-type-body-line-height-xx` variables\n- Removed all `db-type-body-font-size-xx` variables\n- Add new variables `db-type-body-xx` as combination of line-height and font-size\n\n#### Border\n\n- Renamed all `border-height` props to `border-width`\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-migration --type=v100_v200 --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace and there might be unexpected changes of similar wordings to our properties for any other methods, or further code occurrences that don't even refer to properties.\n", "docs/migration/v2.x.x-to-v3.0.0.md": "# Migration (2.x.x) \u27A1 3.0.0\n\n## transparent-hovered/-pressed\n\nWe aligned some variables with design.\n\n`db-adaptive-bg-basic-transparent-hovered` becomes:\n\n- `db-adaptive-bg-basic-transparent-full-hovered`\n- `db-adaptive-bg-basic-transparent-semi-hovered`\n\n`db-adaptive-bg-basic-transparent-pressed` becomes:\n\n- `db-adaptive-bg-basic-transparent-full-pressed`\n- `db-adaptive-bg-basic-transparent-semi-pressed`\n\n## db-button/DBButton type\n\n### `type` property\n\nWe changed the behaviour of the `type` property in the `db-button`/`DBButton` component.\nThose changes will only affect React and Vue users.\nIf you use `onClick` or `@click` you will get `type=button` as default, otherwise it will be `type=submit`.\nYou can still set the `type` property manually, to overwrite this.\nAngular and Web Components users will not be affected by this change, the default will be `button`, because click event listeners can't be undefined in the frameworks.\nPlease provide the correct `type` property in your code anyhow as a best practise.\n\n### `state` property\n\nWe removed the `state` property from the `db-button`/`DBButton` component for now.\nIt wasn't implemented in any framework causing some confusion, and we will reintroduce it in a future version.\n\n## db-card/DBCard\n\n### `behavior='interactive'` change\n\nWe changed the `behavior='interactive'` property not applying `role='button'` and `tabIndex` anymore.\nIf you want to use an interactive card, you should wrap the card with the correct HTML element, like a `button` or an `a` HTML tag:\n\n```html\n<!--Angular-->\n<button type=\"button\">\n <db-card behavior=\"interactive\">\n <!-- card content -->\n </db-card>\n</button>\n\n<!--React/Vue-->\n<button type=\"button\">\n <DBCard behavior=\"interactive\">\n <!-- card content -->\n </DBCard>\n</button>\n```\n\n## breakpoints\n\nWe updated some breakpoints to align with design:\n\n- `$db-screen-size-xs: 360` \u27A1\uFE0F `$db-screen-size-xs: 320`\n- `$db-screen-size-sm: 720` \u27A1\uFE0F `$db-screen-size-sm: 768`\n\n## icon-before/-after\n\nWe renamed the `data-icon-after` and `data-icon-before` properties to `data-icon-trailing` and `data-icon-leading`,\nas well the properties in components to `iconTrailing` and/or `iconLeading`.\nFurthermore, we added the possibility to set a trailing icon on the `db-button`/`DBButton` component.\n\nYou can still use `db-icon`/`icon` in most elements/components, which results in showing the default icon.\nMost of the time this will be the leading icon, but in some cases it might be the trailing icon, depending on the component.\n\n## Aria properties in components\n\n### `db-button`/`DBButton`\n\n- **Removed**: `describedbyid` property, just use `aria-describedby`\n- **Removed**: `ariaexpanded` property, just use `aria-expanded`\n- **Removed**: `ariapressed` property, just use `aria-pressed`\n- **Removed**: `label` property, just use `aria-label`\n\n### `db-link`/`DBLink`\n\n- **Removed**: `selected` property, just use `aria-selected`\n- **Removed**: `current` property, just use `aria-current`\n- **Removed**: `label` property, just use `aria-label`\n\n### `db-navigation`/`DBNavigation`\n\n- **Removed**: `labelledBy` property, just use `aria-labelledby`\n\n### `db-radio`/`DBRadio`\n\n- **Removed**: `describedbyid` property, just use `aria-describedby`\n\n### `db-switch`/`DBSwitch`\n\n- **Removed**: `describedbyid` property, just use `aria-describedby`\n\n### `db-tab-item`/`DBTabItem`\n\n- **Removed**: `controls` property, just use `aria-controls`\n\n### `db-tab-panel`/`DBTabPanel`\n\n- **Removed**: `labelledBy` property, just use `aria-labelledby`\n\n### `db-tag`/`DBTag`\n\n- **Removed**: `disabled` property, use `disabled` on child component like `button` or `a` tag\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-migration --type=v200_v300 --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace and there might be unexpected changes of similar wordings to our properties for any other methods, or further code occurrences that don't even refer to properties.\n", "docs/migration/v3.x.x-to-v4.0.0.md": "# Migration (3.x.x) \u27A1 4.0.0\n\n## Custom Select: renamed `ariaListLabel` property to `listLabel`\n\nDue to Angular 20's handling of properties starting with the phrase \"aria,\" we needed to rename the `ariaListLabel` property to `listLabel`.\n\n## Switch: remove `emphasis` property\n\nThe `emphasis` property has been removed from switch component. In a way this has been replaced by our introduction of Validation to this component.\n\n## Automate migration via CLI\n\nWe provide a CLI tool to auto migrate (the first aspect out of the previous list within) your source code. Use this command in your repository:\n\n```shell\nnpx @db-ux/core-migration --type=v300_v400 --src=./src\n```\n\nPlease check the changes made in your codebase afterwards, as this is mainly a simple search & replace and there might be unexpected changes of similar wordings to our properties for any other methods, or further code occurrences that don't even refer to properties.\n", "docs/migration-template.md": "## General\n\n> **Note**\n> For a general installation or migration process check out this [documentation](https://www.npmjs.com/package/@db-ux/core-components).\n\n## Version / Date\n\n### prop 1\n\n<!-- markdownlint-disable MD060 -->\n\n| Before | Status | After | Description |\n| -------- | :-----: | :-----------: | ----------- |\n| `valueX` | \u{1F501} / \u274C | `valueY` / \u274C | optional |\n| `valueZ` | \u{1F501} / \u274C | `valueZ` / \u274C | optional |\n\n<!-- markdownlint-enable MD060 -->\n\n### prop 2\n\n<!-- markdownlint-disable MD060 -->\n\n| Before | Status | After | Description |\n| -------- | :-----: | :-----------: | ----------- |\n| `valueX` | \u{1F501} / \u274C | `valueY` / \u274C | optional |\n| `valueZ` | \u{1F501} / \u274C | `valueZ` / \u274C | optional |\n\n<!-- markdownlint-enable MD060 -->\n", "docs/release-management.md": '# Release Management\n\nWe aim to provide reliable and consistent releases. Due to dependencies on other projects, as well as our roadmap, we need to actively manage releases and decide on their scope. This is done through frequent alignments.\n\nIn order to support this process, and to gain some insight into the current state of issues, we need to both "tag" and track issues in a standardized and normative wording.\n\nTo do this, we\n\n- use semantic versioning wording in our pull request titles ([`fix:`](https://github.com/db-ux-design-system/core-web/blob/main/docs/conventions.md?plain=1#L11) for bugfixes that would be published in a patch release, and [`refactor:`](https://github.com/db-ux-design-system/core-web/blob/main/docs/conventions.md?plain=1#L11) or [`feat:`](https://github.com/db-ux-design-system/core-web/blob/main/docs/conventions.md?plain=1#L11) for targeting minor releases).\n- still leave them in draft state even when setting it to "in review" state in the [UX Engineering Team Backlog board](https://github.com/orgs/db-ux-design-system/projects/6/views/1)\n- set their status in the [UX Engineering Team Backlog board](https://github.com/orgs/db-ux-design-system/projects/6/views/1) to "ready for release" after reviewing them, so that we have a clear overview of the candidates for the next releases.\n\nBoth the release scope, ensuring that all issues are ready for release, and even also other issues candidates might get pushed to that state, and the merging of Pull Requests on release day are managed by a Release Manager.\n\n## Changesets\n\nFor releasing a new version we\'re using [changesets](.changeset/README.md).\n\n## Repositories\n\nYou would still need to check all repositories for release candidates, that might not be listed within [UX Engineering Team Backlog board](https://github.com/orgs/db-ux-design-system/projects/6/views/1) to "ready for release" column: <https://github.com/db-ux-design-system/.github-private/blob/main/profile/README.md#repositories-mit-ggf-weiteren-release-relevanten-prs>\n', "docs/research/README.md": "# How to research\n\nIf you want to do a research for a new component run this in the `docs` folder:\n\n```shell\nnpm run generate:component-research --workspace=@db-ux/docs\n```\n\n1. Add the name of your component and a new `.md` file will be created.\n2. Use all links to the design systems to check if the component exists and/or if it has another name. Change the link/name according to this.\n3. You can add a comment as an optional field if you find something special in another design system.\n4. Add a conclusion at the end, which covers similarities and possible problems\n\nYou can find more design systems here:\n\n- <https://component.gallery/>\n- <https://github.com/alexpate/awesome-design-systems>\n\nFurther inspirational links:\n\n- <https://handreichungen.bfit-bund.de/barrierefreie-uie/>\n- <https://open-ui.org/>\n\n5. Additionally it might be beneficial to even also already save your HTML explorations within the related components file, like e.g. for `buttons`: `packages/components/src/components/button/index.html`\n", "docs/research/button-group.md": '# DEV Research `button-group`\n\n## Overview \u{1F50D}\n\n| Design System | Repos / Docs | Notes (separate-actions button groups) |\n| --------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Atlassian Design System** | Docs: \u201CButton group\u201D in Button component section | Defines a Button group as a way to \u201Cgive users access to frequently performed, related actions\u201D. It is a wrapper around individual Button components, typically used in toolbars or near a controlled object. Supports mixing appearances (primary, subtle, danger) within one group to express hierarchy. Group itself has no selection state; each button triggers its own action. Recommended for small, focused sets of actions. |\n| **Atlassian Forge UI Kit** | Repo/docs for `ButtonGroup` React component | Simple `ButtonGroup` component that renders multiple Buttons together. Designed for dialogs and inline action areas where each button executes an independent operation. API mainly controls layout (spacing, alignment); there is no built-in toggle/segmented behavior. |\n| **USWDS \u2013 U.S. Web Design System** | `button-group` component docs | The Button group \u201Ccollects similar or related actions\u201D. Examples show primary/secondary pairs such as \u201CBack / Continue\u201D or \u201CSubmit application / Save draft\u201D. Default layout is horizontal with gaps; on small screens the group stacks vertically (each button full-width). Emphasis on WCAG-compliant tap targets and keyboard access. Each button is a standard action button; the group does not track a selected state. |\n| **VA.gov Design System** (USWDS derivative) | Button group in component library | Reuses USWDS\u2019 Button group, sometimes called \u201Cbutton pair\u201D. Encourages use in flows and wizards with one primary and one or two secondary actions. Strong guidance for responsive stacking (buttons become full-width on mobile) and for keeping the group small. |\n| **Other US government DS (e.g. NCI / NCIDS)** | Repositories built on USWDS | Many USWDS-based design systems adopt the same Button group: horizontal layout for desktop, vertical on mobile; buttons are independent actions with primary/secondary styling. Typically limited to 2\u20133 buttons plus a link-style action if needed. |\n| **GitLab Pajamas** | Docs: `Button group` | Distinguishes two conceptual types: (1) **related action buttons** and (2) **related option buttons**. For **related actions**, each button performs an immediate action such as \u201CEdit\u201D, \u201CDelete\u201D, \u201CMove\u201D. The group may visually emphasize one button as primary. There is an optional \u201Cselected on load\u201D state to reflect an existing context, but it is not a persistent segmented control. Guidance recommends keeping groups compact and contextual. |\n| **GitLab Pajamas \u2013 Usage examples** | Pajamas Storybook / examples | Shows action button groups in table rows, toolbars, and card headers. Buttons are mostly tertiary/secondary style or icon-only, with tooltips where labels are not visible. No built-in roving tabindex; focus moves between buttons in DOM order. |\n| **MUI \u2013 Material UI (React)** | Repo: `@mui/material/ButtonGroup` | `ButtonGroup` wraps multiple `Button` components and can propagate `variant`, `color`, `size`, and `orientation` to children. Default use is multiple related actions (e.g., text formatting buttons, grouped submit/cancel actions). Also used as a building block for split buttons. Disables all children when the group is disabled. Can be horizontal or vertical; supports fullWidth. Immediate action behavior; any \u201Cselected\u201D appearance is managed externally by setting button props. |\n| **Joy UI (MUI)** | Repo: `@mui/joy/ButtonGroup` | Similar concept as MUI core but with Joy\u2019s visual language. `ButtonGroup` enforces consistent radius, variant (`solid`, `outlined`, `soft`, `plain`) and size across child Buttons. Recommended for short sets of related actions and simple view filters. Segmented / toggle behavior is handled elsewhere (e.g., by ToggleButtonGroup); by default ButtonGroup is just layout + styling for independent actions. |\n| **Material Design 3** | M3 \u201CButton groups\u201D guidelines | M3 describes \u201Cstandard button groups\u201D (separate actions) and \u201Csegmented button groups\u201D (options). Standard groups are used in toolbars, dialog footers, and cards \u201Cto organize related actions in a single horizontal surface\u201D. M3 explicitly notes that standard button groups fire actions immediately, whereas segmented groups represent a selected state. Visual guidance covers spacing, grouping with rounded corners, and alignment. |\n| **Bootstrap** | Repo: `twbs/bootstrap`, component \u201CButton group\u201D | `.btn-group` is a pure CSS layout utility that groups `.btn` elements on a single line. Used for toolbars and grouped actions. Each button is a regular clickable button or link; Bootstrap does not add selection logic by default (except when used together with JS plugins for toggles). Supports `.btn-group-vertical` and `.btn-toolbar` (multiple groups combined). Examples include icon-only groups and small action clusters. |\n| **Lightning Design System (Salesforce)** | \u201CButton groups\u201D and \u201CButton icons\u201D | Uses Button groups for contextual actions associated with records, views, or toolbars. Often combines icon buttons and text buttons. The group is mainly a layout and styling construct; click behavior is handled on each button. Segmented / stateful behavior is delegated to other components (e.g., tabs, pills). Accessibility guidance recommends `role="group"` and a label to describe the action area. |\n| **IBM Carbon** | Button / Overflow / Toolbar patterns | Carbon does not expose a dedicated \u201CButtonGroup\u201D React component but shows \u201CButton sets\u201D in forms and \u201Ctoolbars\u201D in tables. These are essentially button groups for separate actions (primary and secondary buttons) plus overflow menus. The pattern recommends keeping the main actions visible and grouping no more than a handful of buttons together to avoid overwhelming users. |\n| **Telerik / Kendo UI** | `ButtonGroup` for React / Angular / jQuery | `ButtonGroup` is described as a collection of buttons that act as a single UI element. It supports text-only, icon-only and icon-with-text items. Can be configured for selection modes, but also used as a simple action group where clicking a button invokes a bound handler. Properties include orientation, size, and theme. |\n| **Untitled UI (Figma library)** | Button group variants | Treats Button groups mainly as a **layout / composition pattern**: primary + secondary pairs, sets of equally sized buttons, icon-only action groups. Focus is on hierarchy (one primary button per group), spacing tokens, and responsive wrapping. Recommended size is small groups; larger sets should move to segmented controls, menus, or toolbars with overflow. |\n| **Component Gallery (meta index)** | Entry: `Button group` | Defines a Button group generically as \u201Ca wrapper for related buttons, useful when you want to display multiple related actions together.\u201D Lists many design systems that implement this pattern with small variations. Recommends using `role="group"` or `role="toolbar"` and providing a label that describes the group\u2019s purpose. Notes that for view selection and persistent states, segmented controls or tabs are better suited. |\n\n---\n\n## Conclusion \u{1F3C1}\n\n### What a ButtonGroup is\n\nAcross the surveyed design systems, a **ButtonGroup** for separate actions is consistently understood as:\n\n- A **visual and semantic grouping** of multiple, closely related actions in a shared context (dialog footer, toolbar, card header, table row, etc.).\n- Each button behaves as a **normal action button**: clicking it immediately performs its action.\n- The group itself **does not own a persistent selection state**. If one button appears highlighted (e.g., \u201Ccurrent view\u201D or \u201Cdefault format\u201D), this is usually controlled externally and should not be confused with a segmented control pattern.\n\nFor your design system, this suggests that the first ButtonGroup variant should be positioned as:\n\n> \u201CA container for 2\u20137 related actions, allowing designers and developers to place multiple buttons together while enforcing consistent spacing, alignment, hierarchy and accessibility.\u201D\n\n---\n\n### Behavior & sizing\n\n- **Immediate, single actions:** Every button has its own click handler. The group is not a radio/segmented control and is not used for persistent choices or navigation.\n- **Small sets only:** Most systems implicitly or explicitly expect **2\u20135 buttons**, sometimes up to ~7 for dense toolbars. Larger sets are usually transformed into menus, segmented controls, or toolbars with overflow.\n- **No built-in selection:** If one button is styled differently (e.g., \u201Cprimary\u201D vs \u201Csecondary\u201D), this expresses **hierarchy**, not selection.\n\n---\n\n### Layout & responsive patterns\n\nCommon layout expectations:\n\n- **Horizontal by default** on desktop. Buttons appear in a single row, with consistent horizontal gaps or shared borders.\n- **Vertical stacking on small screens**: USWDS explicitly recommend stacking buttons full-width on small viewports to improve tap targets and readability. Other systems show similar behavior in examples even when not mandated.\n- **Orientation control:** API-level support for `horizontal` vs `vertical` orientation is common in component libraries (MUI, Joy, Telerik). Vertical groups are used for side toolbars or when space is constrained.\n- **Equal vs content width:** Design libraries show both content-width buttons and \u201Cequal width\u201D buttons. Equal width is often used when all actions should appear equally important or when the group fills a container.\n\n---\n\n### Visual styling & hierarchy\n\nPatterns that repeat across systems:\n\n- The group enforces **consistent size and variant** among children (e.g. all small outlined buttons) but may allow **one primary action** to stand out.\n- Primary/secondary hierarchy is often encoded by mixing variants within the same group: e.g. primary filled button + secondary ghost button + tertiary text link.\n- Icon-only buttons are common in **toolbars** but typically require tooltips and/or accessible labels.\n\nThis implies that your ButtonGroup should:\n\n- Reuse existing **Button variants, sizes and tokens**, rather than introducing new unique styles.\n- Define **rules for mixing** (e.g. \u201Cat most one primary per group\u201D, \u201Cicon-only buttons must have tooltips and aria-labels\u201D).\n\n---\n\n### Accessibility & semantics\n\nThe accessibility model is relatively simple and consistent:\n\n- Group container uses `role="group"` for generic clusters of buttons, or `role="toolbar"` when the group is acting as a toolbar controlling another surface.\n- The group must have an accessible label, via:\n - `aria-label` (for icon-only groups), or\n - `aria-labelledby` referencing nearby visible text.\n- Focus stays on individual buttons; **no roving tabindex** is needed. Tab navigation follows DOM order; Space/Enter activates each button as usual.\n- When stacked vertically on mobile, minimum tap target size and contrast rules still apply.\n\n---\n\n### Relationship to segmented controls & navigation\n\nSeveral systems use the same or similar components for both **action groups** and **segmented controls**, but most of them draw a conceptual line:\n\n- Button groups for **actions**: immediate operations; no persistent selection; used around forms, cards, dialogs, and tools.\n- Segmented controls / toggle groups: represent **mutually exclusive or multi-select options**, often changing views or filters; implement radio/tab/checkbox patterns with persistent visual states.\n\nIt is important to:\n\n- Clearly scope this initial ButtonGroup research and implementation to **separate actions only**.\n- Plan **segmented / toggle variants** as either:\n - a separate \u201CSegmentedControl\u201D component, or\n - a later extension of ButtonGroup with different semantics and ARIA patterns.\n\n---\n\n## Possible roadmap based on implementation complexity \u{1F4CD}\n\n### Phase 1 \u2013 Basic action ButtonGroup (current story scope)\n\n**Goal:** Provide a compositional component to group 2\u20137 related action buttons, with minimal API and solid accessibility.\n\n- Implement `<ButtonGroup>` that:\n - Renders a semantic container with `role="group"` by default.\n - Accepts an accessible label (`aria-label` / `aria-labelledby`).\n - Takes existing Button components as children.\n- Layout & styling:\n - Horizontal layout with DS spacing tokens.\n - Optional `orientation="vertical"` for side usage.\n - Optional `fullWidth` / `equalWidth` behavior, if consistent with your layout system.\n- Behavior:\n - No built-in selection logic; each child button handles its own click.\n - Group-level `disabled` prop that disables all children (for loading or unavailable states).\n- Documentation:\n - Definition, anatomy, basic examples (dialog footer, card actions, inline toolbar).\n - Clear distinction from segmented controls and tabs.\n\n### Phase 2 \u2013 Toolbar / icon-heavy groups\n\n**Goal:** Extend ButtonGroup for toolbar-like use cases with icons, compact spacing and more responsive behavior.\n\n- Add `role="toolbar"` option and usage guidelines (must have label).\n- Define recommended patterns for icon-only buttons (tooltips, focus styles, minimum size).\n- Introduce patterns for:\n - Multiple groups inside a toolbar (e.g., alignment left/right).\n - Optional overflow pattern when there are more than 5\u20137 actions.\n\n### Phase 3 \u2013 Relationship to advanced patterns (out of current scope)\n\n**Goal:** Use ButtonGroup as the foundation for more complex components.\n\n- **Split Button**: One primary action + dropdown trigger button; visually and structurally a special case of ButtonGroup with exactly two children.\n- **Segmented / toggle groups**: Single- or multi-select option groups based on radio/checkbox/tab patterns.\n- **View switchers & filters**: Higher-level patterns that may be implemented on top of ButtonGroup but with distinct semantics.\n', "docs/research/focus-state.md": '<!-- markdownlint-disable MD013 -->\n\n# DEV Research focus-state\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [focus outline visible e.g. on button](https://atlassian.design/components/button/examples) | `:focus-visible { outline: 2px solid var(--ds-border-focused, #2684FF); outline-offset: 2px; --ds-border-focused: #85B8FF; }` |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [focus "outline" visible e.g. on input](https://getbootstrap.com/docs/4.3/components/forms/) | `:focus { border-color: #80bdff;outline: 0;box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25); }` and background-colors matching box-shadows e.g. on [buttons](https://getbootstrap.com/docs/4.3/components/buttons/) |\n| [GitHub Primer](https://github.com/primer/css) | [focus "outline" visible e.g. on button](https://primer.style/design/components/button/react) | `:focus-visible:not(:disabled) { box-shadow: none; outline: rgb(9, 105, 218) solid 2px; outline-offset: -2px; }`; also provide a [detailed explanation](https://primer.style/design/guides/accessibility/focus-management) |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [focus "outline" visible e.g. on button](https://design.gitlab.com/components/button) | `:focus { box-shadow: inset 0 0 0 1px #89888d, 0 0 0 1px #fff, 0 0 0 3px #428fdc; outline: none; background-color: #ececef;}` ; also provide an [explanation](https://design.gitlab.com/accessibility/keyboard-only#focus-states) |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [focus `box-shadow` visible e.g. on button](https://storybook.grommet.io/?path=/story/controls-button-active--active) | `:focus { outline: none; box-shadow: rgb(111, 255, 176) 0px 0px 2px 2px; }` |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [focus `border-color` and `box-shadow` visible e.g. on button](https://carbondesignsystem.com/components/overview/) | `outline: none;` with an additional `:focus { border-color: var(--cds-button-focus-color, var(--cds-focus, #0f62fe)); box-shadow: inset 0 0 0 1px var(--cds-button-focus-color, var(--cds-focus, #0f62fe)),inset 0 0 0 2px var (--cds-background, #ffffff); }`; also provide a general [explanation](https://www.ibm.com/able/requirements/requirements/?version=7_1#2_4_7) |\n| [MUI](https://github.com/mui/material-ui) | [widely used focus-state e.g. on tabs](https://mui.com/material-ui/react-tabs/) | several different, component specific stylings; also provide a general [explanation](https://mui.com/base-ui/getting-started/accessibility/#focus-ring) |\n| [MongoDB.design](https://github.com/mongodb/design) | [focus `background-color` and `box-shadow` visible e.g. on button](https://www.mongodb.design/component/button/example/) | `:focus-visible { background-color: rgb(255, 255, 255); box-shadow: rgb(255, 255, 255) 0px 0px 0px 2px, rgb(4, 152, 236) 0px 0px 0px 4px; }` |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [focus-state by pseudo-element e.g. on button](https://designsystem.porsche.com/v3/components/button/examples) | `:focus::before { content: ""; position: fixed; border: 2px solid rgb(26, 68, 234);border-radius: 8px; inset: -6px; }` |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [focus-state by pseudo-element e.g. on header elements](https://lyne-storybook.app.sbb.ch/?path=/docs/pages-home--docs) | `:host(:focus-visible:not([data-focus-origin="mouse"], [data-focus-origin="touch"])) .sbb-header-action::before { outline-offset: var(--sbb-focus-outline-offset); outline: var(--sbb-focus-outline-color) solid var(--sbb-focus-outline-width); }` and `.sbb-header-action::before { position: absolute; content: ""; inset: var(--sbb-header-action-background-inset);border-radius: var(--sbb-border-radius-infinity);background-color: var(--sbb-header-action-background-color);transition-duration: var(--sbb-header-action-transition-duration);transition-timing-function: var(--sbb-header-action-transition-easing); transition-property: inset, background-color; border: var(--sbb-border-width-1x) solid var(--sbb-header-action-border-color); }` |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [focus-state by `outline` and `box-shadow` e.g. on button](https://polaris.shopify.com/components/actions/button) | `.Polaris-Button:focus-visible { box-shadow: var(--p-shadow-200); outline: var(--p-border-width-050) solid var(--p-color-border-focus); outline-offset: var(--p-space-025); }` |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [focus-state by `outline` e.g. on button](https://wcs.dev.sncf/?path=/docs/components-button--documentation) | `.wcs-inner-button:focus-visible { outline: 2px dashed var(--wcs-primary); outline-offset: 4px; border-radius: var(--wcs-button-border-radius); }` |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [focus-state e.g. on buttons](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/buttons) | regular browser defaults like e.g. `:focus-visible { outline: -webkit-focus-ring-color auto 1px; }` |\n| [Telekom Scale](https://github.com/telekom/scale) | [focus-state by `outline` e.g. on button](https://telekom.github.io/scale/?path=/docs/components-button--standard) | `.button:not(.button--disabled):focus { outline: var(--telekom-line-weight-highlight) solid var(--color-focus); outline-offset: var(--telekom-spacing-composition-space-01); }` |\n| [Washington Post Design System](https://build.washingtonpost.com/) | [focus-state e.g. on button](https://build.washingtonpost.com/components/button) | `@media screen and (-webkit-min-device-pixel-ratio: 0) :focus-visible { outline: 1px auto -webkit-focus-ring-color; }` overwriting another `:focus-visible { outline: 1px auto Highlight; }` |\n\n## Conclusion\n\n- _GitHub Primer_ has a quite interesting approach to focus states. By shifting the outline to the inside of the element (negative `outline-offset`), you get a quite universal approach if even also mixing it with having the `outline-color` defined by the `currentColor` keyword, as this needs to be accessible to the elements / components background anyhow and you wouldn\'t have the problem with diverse underlying contents like e.g. images behind the element / component, as you only consider the elements background itself.\n', "docs/research/footer.md": '# DEV Research footer\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | \u274C | -- |\n| [Bootstrap](https://github.com/twbs/bootstrap) | \u274C | -- |\n| [GitHub Primer](https://github.com/primer/css) | \u274C | -- |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | \u274C | -- |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [footer](https://v2.grommet.io/footer) | Simple container with alignment, padding, fill... Does not offer any layout like columns. |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | \u274C | -- |\n| [Material UI](https://github.com/mui/material-ui) | \u274C | -- |\n| [MongoDB.design](https://github.com/mongodb/design) | \u274C | -- |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | \u274C | -- |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [footer](https://lyne-storybook.app.sbb.ch/?path=/docs/elements-sbb-footer--docs) | Footer is a simple wrapper that provides a slot to add any layouts and components. Nice: the footer is often displayed with the sbb-clock component (a stylised, animated station clock). |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | \u274C | -- |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | \u274C | -- |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | \u274C | |\n| [Telekom Scale](https://github.com/telekom/scale) | [footer](https://telekom.github.io/scale/?path=/docs/components-telekom-footer--standard) | Footer contains a Telekom logo. There are slots for a legal line and a list of links. |\n| [Washington Post Design System](https://build.washingtonpost.com/) | \u274C | |\n\n## Conclusion\n\nMost design systems do not offer a footer component. The few footers are rather simple, styled (background colour, centring) wrappers that offer one or more slots for any lists and components. For example, to display several links.\n\nThe assumption here is that footers are often very individually structured, so that overly strict specifications on the part of the design system would be too **restrictive**.\n\n## Thoughts on implementation\n\n### Mobile Accordion\n\n\u{1F9E0} _Link lists are summarised in an accordion on mobile so that the footer appears shorter and tidier._\n\n\u2753Links within collapsed accordion items are not read out by screen readers, only when the item is expanded. The page search does not find these links either. **Presumably this is not a11y compliant.**\n\n### data props versus component driven\n\n\u{1F9E0} _Should the contents of the footer be transferred exclusively as data per property? Or are the contents mainly assembled "manually" via various (sub)components?_\n\n#### data props only\n\n**Pro**\n\n- easier to use for devs\n- the integrity of the footer is guaranteed. a standardised look is maintained.\n\n**Contra**\n\n- not consistent with the approach of existing components\n- not very flexible\n- links cannot be customised, which may be necessary depending on the framework\n\n#### (sub)components only\n\n**Pro**\n\n- flexible in use\n- standardised use within the DST\n- structure of the footer is represented in the template\n\n**Contra**\n\n- devs must strictly follow the docs to build a footer\n- there are no active guides, such as code completion or type checking, when using the footer component\n- potentially more errors are possible\n- devs need to write more code in the template\n', "docs/research/heading.md": '# DEV Research heading\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [heading](https://atlassian.design/components/heading/examples) | `<h1-h6>` based on `as` property, arrangement with other text styles with stack |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [headings](https://getbootstrap.com/docs/4.3/content/typography/#headings) | no extra component, only class to change visual |\n| [GitHub Primer](https://github.com/primer/css) | [heading](https://primer.style/product/components/heading/) | `<h1-h6>` based on `as` property |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [type-headings](https://design.gitlab.com/product-foundations/type-headings) | no extra component, only class to change visual |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [heading](https://v2.grommet.io/heading) | `<h1-h6>` based on `as` property |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [heading-styles](https://carbondesignsystem.com/elements/typography/type-sets/#fixed-heading-styles) | no extra component, breakpoint based size changes (fluid styles) |\n| [Material UI](https://github.com/mui/material-ui) | [Typography](https://mui.com/material-ui/react-typography/#usage) | `<h1-h6>` based on `variant` |\n| [MongoDB.design](https://github.com/mongodb/design) | [typography](https://www.mongodb.design/component/typography/live-example) | no extra component |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [heading](https://designsystem.porsche.com/v3/components/heading/configurator/) | `<h1-h6>` based on `tag` |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [title](https://lyne-storybook.app.sbb.ch/?path=/docs/elements-sbb-title--docs) | `<h1-h6>` based on `level`, extra `visual-level` |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [Text](https://polaris-react.shopify.com/components/typography/text) | `<Text variant="heading3xl" as="h2">` |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [headings](https://designmetier-bootstrap.sncf.fr/docs/4.3/content/typography/#headings) | no extra component |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [title](https://mistica-web.vercel.app/?path=/story/components-titles--title-4-story) | `<h1-h6>` based on extra component |\n| [Telekom Scale](https://github.com/telekom/scale) | [typography](https://telekom.github.io/scale/?path=/docs/guidelines-typography--page) | no extra component |\n| [Washington Post Design System](https://build.washingtonpost.com/) | [typography](https://build.washingtonpost.com/foundations/typography/) | no extra component |\n\n## Conclusion\n\n- We should use a `<DBHeading>` component with `as` property and use a `<Show when={props.as === "h1"}><h1>{children}</h1></Show>`\n\n### Questions for dev\n\n- How to handle DB Pulse??\n - We handle this inside the `@db-ux/db-theme` package\n- Shall we add auto-spacing as dev property (h1+h2, add margin)??\n - We won\'t do this for now\n\n### Questions for design\n\n- Shall we really add the margins as property or use stack?\n - We use `props.paragraphSpacing` with `1lh` instead of stack:\n ```tsx\n <DBHeading as="h1" paragraphSpacing>\n Heading 1\n </DBHeading>\n <DBHeading as="h2" paragraphSpacing>\n Heading 2\n </DBHeading>\n <DBStack variant="paragraph" gap="md">\n <DBText>ABCD</DBText>\n <DBText>ABCD</DBText>\n </DBStack>\n ```\n- Fluid Styles might be a cool feature?\n - We already have this feature because of our responsive typography\n- [`text-wrap`](https://developer.chrome.com/docs/css-ui/css-text-wrap-balance)-CSS-property (especially with the value `"balance"`) would be a relevant aspect to think about\n', "docs/research/list-and-menu.md": '# DEV Research list\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [menu](https://atlassian.design/components/menu) / [dropdown-menu](https://atlassian.design/components/dropdown-menu) | `<div role="group">` + `<button>`, `<Section>` component with `heading` property, scrolling for complete menu or only for sections |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [list-group](https://getbootstrap.com/docs/4.3/components/list-group/) | `<ul>` + `<li>` for static content, `<div>` + `<a>` for interactive, badge as possible content |\n| [GitHub Primer](https://github.com/primer/css) | [action-list](https://primer.style/product/components/action-list/) | `<ul>` + `<li>` + `<button>`, trailing action extra button, `showDividers` on list component, inline and block descriptions |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | \u274C | -- |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [list](https://v2.grommet.io/list) / [menu](https://v2.grommet.io/menu) | `<ul role="listbox">` + `<li role="option" tabindex="1">` , `<div role="menu">` + `<button role="menuitem">` |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [contained-list](https://carbondesignsystem.com/components/contained-list) | `<div>` + `<header id="header">` + `<ul aria-labelledby="header">` + `<li>` + `<button>` |\n| [Material UI](https://github.com/mui/material-ui) | [list](https://mui.com/material-ui/react-list/) | `<ul>` + `<li>` + `<hr>` + `<div role="button">` |\n| [MongoDB.design](https://github.com/mongodb/design) | [menu](https://www.mongodb.design/component/menu/live-example) | `<ul role="menu">` + `<li role="none">` + `<button role="menuitem">`, `<li role="separator">` , `aria-current="true"` with indicator + green background |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | \u274C | -- |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [menu](https://lyne-storybook.app.sbb.ch/?path=/docs/elements-sbb-menu-sbb-menu--docs) | no `<ul>` just `role="menuitem"` on child elements |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [lists](https://polaris-react.shopify.com/components/lists) | different list components for every use-case, `<ul><li><div><h6>Section title</h6><ul>List Items</ul></div></li></ul>` |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [list-group](https://designmetier-bootstrap.sncf.fr/docs/4.3/components/list-group/) | simple `<ul>` + `<li>` |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [lists](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/lists) / [menu](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/menu) | `<div role="list">` + `<div role="listitem">` + `<button>` |\n| [Telekom Scale](https://github.com/telekom/scale) | [flyout-menu](https://telekom.github.io/scale/?path=/docs/components-flyout-menu--cascading-menu) / \u274C | `<div role="menu">` + `<div role="menuitem">`, extend other menu with click not hover |\n| [Washington Post Design System](https://build.washingtonpost.com/) | \u274C | -- |\n\n## Conclusion\n\n- We might add those components:\n - `<DBList>`\n - `<DBListGroup>`\n - `<DBListGroupTitle>`\n - `<DBListItem>`\n - optional subcomponents to work with `:has()` and grid:\n - `<DBListItemContentStart>`\n - `<DBListItemContentEnd>`\n - See [Example in HTML](#example-what-should-be-rendered-in-html)\n- Based on the children inside `<DBListItem>` we might change the role of the `DBList` or `DBListGroup`\n - maybe we could just use the normal list semantics even for `<button>` or `<input/>` with additional JS for keyboard navigation, but we need to check how screen-readers will handle this\n - there should be also a property like `semanticRole="list" | "menu"` to override the default behavior and skip the check for children\n - if children are `<button>` and `<a>` we might use `role="menu"` + `role="menuitem"`\n - we need to check if how we can support `details` + `summary` inside a slot of `<DBListItem>`, maybe with `display: grid` and `subgrid`\n- The "Menu" component will be an example `<DBPopover>` + `<DBList>`\n- An `orientation` property on `DBList` and/or `DBListGroup` will handle the layout for `<DBListItem>`:\n - `horizontal` (Default):\n - ```css\n grid-template-areas:\n "content-start icon text icon-trailing content-end"\n "content-start icon description icon-trailing content-end";\n ```\n - `vertical`:\n - ````css\n grid-template-areas:\n "content-start content-start"\n "icon icon"\n "text text"\n "description icon-trailing"\n "content-end content-end";\n ```\n ````\n- `DBListGroup` has property `showDivider`, which might be a Mitosis component like this:\n - `<Fragment><li class="db-list-group"></li><Show when={showDivider}><li class="db-list-divider"></li></Show></Fragment>`\n - Maybe we should use `variant="divider"` on `DBList` to handle this for all `DBListGroup` ???\n - `variant="divider"` would allow us to use `variant="card"` to align with `DBAccordion` and `DBTable`\n- `overflow` for `DBList` and `DBListGroup`\n- `width`: `auto` or `full` for `DBListGroup`\n- `<input type="checkbox">` or `<input type="radio">` with `:checked` will have `basic-bg-level-2`\n- `disabled` property for `DBListItem`\n- `descriptionVariant`: `block` and `inline` for `DBListItem`\n- `noText` on `DBListGroup` & `DBList` to achieve example icon only menu\n- We need to handle keyboard navigation for interactive items see [JS Keyboard Navigation](#js-keyboard-navigation) for resources and examples\n\n### JS Keyboard Navigation\n\n- [MDN Menu/Group/MenuItem Example](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/group_role#:~:text=The%20following%20example%20uses%20the%20group%20role%20with%20a%20drop%2Ddown%20menu%20containing%20menuitems%3A)\n- W3 Aria Patterns:\n - [Listbox](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/)\n - [Menu](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/)\n\n- Interesting aria-roles:\n - [aria-activedescendant](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-activedescendant)\n\n### Example what should be rendered in HTML\n\n```html\n<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>Title</title>\n <style>\n ul,\n li {\n list-style: none;\n }\n\n [role="separator"] {\n /* We need some content to enforce screen-reader to read "separator" */\n &::before {\n content: "---";\n height: 1px;\n border-top: 1px solid black;\n display: block;\n font-size: 0;\n }\n }\n </style>\n </head>\n <body>\n <!-- <DBList> -->\n <div class="db-list">\n <ul aria-label="List 1">\n <!-- <DBListGroup> -->\n <li class="db-list-section" aria-labelledby="section-1">\n <!-- <DBListGroupTitle> -->\n <div class="db-list-group-title" id="section-1">\n Section 1\n </div>\n <ul>\n <!-- <DBListItem>-->\n <li class="db-list-item">Test 1</li>\n <li class="db-list-item">Test 2</li>\n <li class="db-list-item">Test 3</li>\n </ul>\n </li>\n <!-- showDivider inside <DBListGroup> -->\n <li class="db-list-divider" role="separator"></li>\n <li class="db-list-section" aria-labelledby="section-2">\n <div class="db-list-group-title" id="section-2">\n Section 2\n </div>\n <ul>\n <li class="db-list-item">Test 4</li>\n <li class="db-list-item">Test 5</li>\n <li class="db-list-item">Test 6</li>\n </ul>\n </li>\n </ul>\n </div>\n </body>\n</html>\n```\n\n### Examples for JSX usage\n\n#### Simple example without Groups\n\n```tsx\n// static\nconst App = () => {\n return (\n <DBList>\n <DBListItem>Item 1</DBListItem>\n <DBListItem>Item 2</DBListItem>\n <DBListItem>Item 3</DBListItem>\n </DBList>\n );\n};\n```\n\n```tsx\n// interactive button\nconst App = () => {\n return (\n <DBList>\n <DBListItem>\n <button>Item 1</button>\n </DBListItem>\n <DBListItem>\n <button>Item 2</button>\n </DBListItem>\n <DBListItem>\n <button>Item 3</button>\n </DBListItem>\n </DBList>\n );\n};\n```\n\n```tsx\n// interactive link\nconst App = () => {\n return (\n <DBList>\n <DBListItem>\n <a href="#">Item 1</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Item 2</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Item 3</a>\n </DBListItem>\n </DBList>\n );\n};\n```\n\n```tsx\n// interactive checkbox\nconst App = () => {\n return (\n <DBList>\n <DBListItem>\n <label>\n Item 1\n <input type="checkbox" />\n </label>\n </DBListItem>\n <DBListItem>\n <label>\n Item 2\n <input type="checkbox" />\n </label>\n </DBListItem>\n <DBListItem>\n <label>\n Item 3\n <input type="checkbox" />\n </label>\n </DBListItem>\n </DBList>\n );\n};\n```\n\n```tsx\n// contentEnd links\nconst App = () => {\n return (\n <DBList>\n <DBListItem\n contentEnd={\n <details>\n <summary>I should be a ghost button</summary>\n <DBList>\n <DBListItem>\n <a href="#">Sub-Item 1</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Sub-Item 2</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Sub-Item 3</a>\n </DBListItem>\n </DBList>\n </details>\n }\n >\n <a href="#">Item 1</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Item 2</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Item 3</a>\n </DBListItem>\n </DBList>\n );\n};\n```\n\n```tsx\n// contentEnd popover\nconst App = () => {\n return (\n <DBList>\n <DBListItem\n contentEnd={\n <DBPopover\n trigger={\n <DBButton\n variant="ghost"\n icon="chevron_left"\n noText\n >\n Hover on me\n </DBButton>\n }\n >\n <DBList>\n <DBListItem>\n <a href="#">Sub-Item 1</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Sub-Item 2</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Sub-Item 3</a>\n </DBListItem>\n </DBList>\n </DBPopover>\n }\n >\n Item 1\n </DBListItem>\n <DBListItem>\n <a href="#">Item 2</a>\n </DBListItem>\n <DBListItem>\n <a href="#">Item 3</a>\n </DBListItem>\n </DBList>\n );\n};\n```\n\n### With Groups\n\n```tsx\n// static\nconst App = () => {\n return (\n <DBList>\n <DBListGroup showDivider>\n <DBListItem>Item 1</DBListItem>\n <DBListItem>Item 2</DBListItem>\n <DBListItem>Item 3</DBListItem>\n </DBListGroup>\n <DBListGroup>\n <DBListItem>Item 4</DBListItem>\n <DBListItem>Item 5</DBListItem>\n <DBListItem>Item 6</DBListItem>\n </DBListGroup>\n </DBList>\n );\n};\n```\n\n```tsx\n// \u274C invalid example mixing DBListItem and DBListGroup\nconst App = () => {\n return (\n <DBList>\n <DBListItem>Item 1</DBListItem>\n <DBListItem>Item 2</DBListItem>\n <DBListItem>Item 3</DBListItem>\n <DBListGroup>\n <DBListItem>Item 4</DBListItem>\n <DBListItem>Item 5</DBListItem>\n <DBListItem>Item 6</DBListItem>\n </DBListGroup>\n </DBList>\n );\n};\n```\n', "docs/research/multi-select.md": '# DEV Research multi-select\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [multi-select](https://atlassian.design/components/select/examples#multi-select) | tags with divs + `input` (no filter) with `aria-autocomplete="list"` `aria-expanded="false"` `aria-haspopup="true"` `role="combobox"` + creates dropdown in dom on click |\n| [Bootstrap](https://github.com/twbs/bootstrap) | \u274C | -- |\n| [GitHub Primer](https://github.com/primer/css) | [selectpanel](https://primer.style/components/selectpanel/react/alpha) | tags inside button as `span` + button with `aria-expanded="false"` + extra container with filter input and checkbox group |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [dropdown-combobox](https://design.gitlab.com/components/dropdown-combobox) | tags inside button as `span` + `button` with `aria-haspopup="listbox"` + extra container with filter input and list buttons |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [selectmultiple](https://v2.grommet.io/selectmultiple) | tags inside input as `text` + input + extra container with filter input and checkbox group |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [multi-select](https://react.carbondesignsystem.com/?path=/docs/components-multiselect--overview) | tags with remove button + `button` or `input` with `aria-haspopup="listbox"` + extra container checkbox group |\n| [Material UI](https://github.com/mui/material-ui) | [Combobox](https://mui.com/material-ui/react-autocomplete/) | tags with remove button + `input` with `aria-expanded` &`role=combobox` + extra container list buttons |\n| [MongoDB.design](https://github.com/mongodb/design) | [combobox](https://www.mongodb.design/component/combobox/live-example) | tags with remove button (tabbable) + `input` with `aria-expanded` & `role=combobox` + extra container checkbox group |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [multi-select](https://designsystem.porsche.com/v3/components/multi-select/examples) | tags inside input as `text` + input with filter + extra container and checkbox group |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [multi-select](https://lyne-storybook.app.sbb.ch/?path=/story/elements-sbb-select--multiple-select) | only divs + extra container and checkbox group |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [combobox](https://polaris.shopify.com/components/selection-and-input/combobox?example=combobox-with-multi-select-and-vertical-content) | tags with remove button (tabbable) + `input` with `aria-expanded` &`role=combobox` + extra container checkbox group |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [multi-select](https://designmetier-bootstrap.sncf.fr/docs/4.3/components/select/#multiple) | sr-only `select` + extra container with list buttons |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | \u274C | -- |\n| [Telekom Scale](https://github.com/telekom/scale) | \u274C | -- |\n| [Washington Post Design System](https://build.washingtonpost.com/) | \u274C | -- |\n\n## Conclusion\n\n- Often named [Combobox](https://component.gallery/components/combobox/) or Autocomplete or Autosuggest\n- [combobox_role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/combobox_role)\n- [combobox example w3](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)\n\nWe should work with the button + checkbox approach. Maybe we can replace `button` with `details` + `summary`. Furthermore, out filtering (search input) will be inside the dropdown/menu (see design). We may use `DBSelectOptionType` for the checkboxes to reflect groups etc.\nTags should be our `DBTag` with close function or a `span` based on the props we should change it like this variant="tags|overflow|amount".\n', "docs/research/spinner.md": '# DEV Research spinner\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [spinner](https://atlassian.design/components/spinner/examples) | `<svg>` with CSS animation, fade-in animation to replace content, spinner over content |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [spinner](https://getbootstrap.com/docs/4.3/components/spinners/) | `<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>` , plus animation as alternative, inside `<button>` with `aria-hidden` |\n| [GitHub Primer](https://github.com/primer/css) | [spinner](https://primer.style/product/components/spinner/) | `svg` with CSS animation |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [spinner](https://design.gitlab.com/components/spinner) | multiple `<div>` with animation, loading text optional |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [spinner](https://v2.grommet.io/spinner) | multiple `<div>` with animation, rotation property to change clock-wise animation |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [inline-loading](https://carbondesignsystem.com/components/inline-loading/usage/) | `<svg>` with CSS animation, Specify the loading status \'inactive\' \'active\' \'finished\' \'error\' |\n| [Material UI](https://github.com/mui/material-ui) | [progress](https://mui.com/material-ui/react-progress/) | `svg` with CSS animation, `<CircularProgress>` Component, label inside circle for 90% |\n| [MongoDB.design](https://github.com/mongodb/design) | [loading-indicator](https://www.mongodb.design/component/loading-indicator/live-example) | `<svg>` with CSS animation, |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [spinner](https://designsystem.porsche.com/v3/components/spinner/configurator/) | `<span role="alert" aria-live="assertive"></span>` + `<svg>` with CSS animation |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [loading-indicator-circle](https://lyne-storybook.app.sbb.ch/?path=/docs/elements-sbb-loading-indicator-circle--docs) | another [loading indicator](https://lyne-storybook.app.sbb.ch/?path=/docs/elements-sbb-loading-indicator--docs) , `<span>` with CSS animation, |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [spinner](https://polaris-react.shopify.com/components/feedback-indicators/spinner) | `<svg>` with CSS animation, `hasFocusableParent: Allows the component to apply the correct accessibility roles based on focus.` |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | \u274C | -- |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [spinner](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/spinner) | `<svg role="progressbar">` with CSS animation, |\n| [Telekom Scale](https://github.com/telekom/scale) | [loading-spinner](https://telekom.github.io/scale/?path=/docs/components-loading-spinner--standard) | `<svg>` with CSS animation, alignment: \'horizontal\' \'vertical\' |\n| [Washington Post Design System](https://build.washingtonpost.com/) | \u274C | -- |\n\n## Conclusion\n\n- We could use a `<span>` with a `:before` as "track" and `:after` as "segment"\n- We could use a `<svg>` instead to align styles with design and possible native mobile development. Not recommended if we have different loading indicators.\n- Good hint from [this](https://design.gitlab.com/components/spinner#behavior): A 100ms delay occurs before showing a spinner to mitigate unnecessary spinners showing up at the same time when load times are minimal.\n\n### Questions for dev\n\n- role="status" or role="alert" for Screen-Readers??\n- What shall we do if users disable animations with `prefers-reduced-motion: reduce`?? Maybe we can show some icon instead.\n\n### Questions for design\n\n- Maybe we should name it `Loading Indicator` to use more animations than a spinner??\n- There might be a `CircularProgress` component. Is this confusing for users??\n- How to for interactive components like `DBButton`??\n- Loading status `active`, `successful`, `critical`??\n- Alignment `horizontal`, `vertical` for spinner+text ??\n- Label below or inside circle??\n', "docs/research/stack.md": '# DEV Research stack\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [stack](https://atlassian.design/components/primitives/stack/examples) | `display:flex` |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [flex](https://getbootstrap.com/docs/4.3/utilities/flex/) | `display:flex`, |\n| [GitHub Primer](https://github.com/primer/css) | [stack](https://primer.style/components/stack) | `display:flex` |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | \u274C | -- |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [stack](https://v2.grommet.io/stack) | This `stack` is different to what we expect |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | \u274C | -- |\n| [Material UI](https://github.com/mui/material-ui) | [stack](https://mui.com/material-ui/react-stack/) | `display:flex`, nice: [Dividers](https://mui.com/material-ui/react-stack/#dividers) |\n| [MongoDB.design](https://github.com/mongodb/design) | \u274C | -- |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [flex](https://designsystem.porsche.com/v3/components/flex/examples) | `display:flex`, deprecated |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | \u274C | -- |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [block-stack](https://polaris.shopify.com/components/layout-and-structure/block-stack) & [inline-stack](https://polaris.shopify.com/components/layout-and-structure/inline-stack) | `display:flex`, split into 2 different components |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [stack](https://designmetier-bootstrap.sncf.fr/docs/4.3/utilities/flex/) | `display:flex` |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [stack](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/fundamentals/spacing:69673) | some pattern? |\n| [Telekom Scale](https://github.com/telekom/scale) | \u274C | -- |\n| [Washington Post Design System](https://build.washingtonpost.com/) | \u274C | -- |\n\n## Conclusion\n\nIt\'s just the regular [flex](https://developer.mozilla.org/en-US/docs/Web/CSS/flex) as a component.\nOnly MUI is adding some additional features with "divider".\nShopify Polaris splits the component for "row" and "column" flex into 2 components.\n', "docs/research/switch-and-toggle.md": '<!-- markdownlint-disable-file MD013 -->\n\n# DEV Research Switch / Toggle\n\n## Overview\n\n| Design System | Component(s) | Comment |\n| :-------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Telekom Scale](https://telekom.github.io/scale) | [Switch](https://telekom.github.io/scale/?path=/docs/components-switch--standard), [Tag](https://telekom.github.io/scale/?path=/docs/components-tag--standard), [Chip](https://telekom.github.io/scale/?path=/docs/components-chip--standard) | Switch uses `<input type="checkbox">`, where as Tag is _not interactive_ |\n| [SBB](https://angular.app.sbb.ch/angular/components/) | [Toggle](https://angular.app.sbb.ch/angular/components/toggle/examples), [interactive Tag](https://angular.app.sbb.ch/angular/components/tag/examples) with disabled state, [Chip](https://angular.app.sbb.ch/angular/components/chips/examples) | Toggle is our Tab Bar; in their examples they use a simple [Button](https://angular.app.sbb.ch/angular/components/badge/examples) to toggle states; Chip is used for filtering |\n| [SNCF Design M\xE9tier](https://designmetier-bootstrap.sncf.fr/) | [Switch](https://designmetier-bootstrap.sncf.fr/docs/4.3/components/checkboxes-and-radios/), [Options](https://designmetier-bootstrap.sncf.fr/docs/4.3/components/checkboxes-and-radios/) [Button Tag](https://designmetier-bootstrap.sncf.fr/docs/4.3/components/buttons/) | as `<input>` elements |\n| [IBM Carbon](https://carbondesignsystem.com/components) | [Toggle](https://carbondesignsystem.com/components/toggle/usage/), [Tag](https://carbondesignsystem.com/components/tag/usage/) | Tag component is not interactive; Switch is implemented with simple `div` |\n| [Google Material](https://material-web.dev/components) | [Switch](https://material-web.dev/components/switch), [Interactive Chip](https://material-web.dev/components/chip/#interactive-demo) | `<label>[\u2026]<input type="checkbox" role="switch"></label>` or for Chip `role="option"` |\n| [Porsche Design System](https://designsystem.porsche.com/v3/components/switch/examples) | [Switch](https://designsystem.porsche.com/v3/components/switch/examples), [Tag Dismissable](https://designsystem.porsche.com/v3/components/tag-dismissible/examples) | and _Tag_ component.<br/>Only as Web Component |\n| [Washington Post](https://build.washingtonpost.com/components) | [Switch](https://build.washingtonpost.com/components/switch) | `<button type="button" role="switch" aria-checked="true" data-state="checked" value="on" [\u2026]` |\n\n## Conclusion\n\n### HTML implementation\n\nThere are two ways to build a switch/toggle component:\n\n1. As an input `<input type="checkbox" role="switch">`\n2. As a button with aria role switch `<button type="button" role="switch" aria-checked="true" data-state="checked" value="on" [\u2026]`\n\nAccording to [w3.org](https://www.w3.org/WAI/ARIA/apg/patterns/switch/) there is no explicit recommendation due to a11y issues which implementation suits best. Instead the recommend the following semantic issues:\n\n- The switch has `role="switch"`\n- The switch has an accessible label provided by one of the following:\n - Visible text content contained within the element with role switch.\n - A visible label referenced by the value of `aria-labelledby` set on the element with role switch.\n - `aria-label` set on the element with role switch.\n- When on, the switch element has state `aria-checked` set to `true`.\n- When off, the switch element has state `aria-checked` set to `false`.\n- If the switch element is an HTML `<input type="checkbox">`, it uses the HTML `checked` attribute instead of the `aria-checked` property.\n- If a set of switches is presented as a logical group with a visible label, either:\n - The switches are included in an element with `role="group"` that has the property `aria-labelledby` set to the ID of the element containing the group label.\n - The set is contained in an HTML `fieldset` and the label for the set is contained in an HTML legend element.\n- If the presentation includes additional descriptive static text relevant to a switch or switch group, the switch or switch group has the property `aria-describedby` set to the ID of the element containing the description.\n\n### CSS\n\n[Google](https://web.dev/building-a-switch-component/) wrote a detailed article how to develop a switch component with e.g. the use of [Grid Tracks](https://developer.mozilla.org/en-US/docs/Glossary/Grid_Tracks).\n\n### MDN\n\n<https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/switch_role>\n', "docs/research/table.md": '# DEV Research `table`\n\n## Overview \u{1F50D}\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [table](https://atlassian.design/components/table) / [table-tree](https://atlassian.design/components/table-tree/) | _Table_: interactive data table with built-in pagination, sorting, and column reordering.<br />_Table Tree_: hierarchical table with expandable, nested rows. |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [table](https://getbootstrap.com/docs/4.3/content/tables/) | Static tables styled via CSS classes (striped rows, borders). Responsive behavior via `.table-responsive wrapper` for horizontal scrolling. No built-in interactivity (sorting, etc. requires custom scripts). |\n| [GitHub Primer](https://github.com/primer/css) | [data-table](https://primer.style/product/components/data-table/) | React component with column definitions and custom cells. Advanced features like sorting, selectable rows, sticky headers, etc. Currently no built-in pagination. |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [table](https://design.gitlab.com/components/table) | Table with Basic, Striped, Condensed variants, sortable columns, pagination, responsive scroll. Underlying implementation in Vue/Rails (`<gl-table-lite>`) using Bootstrap-Vue. |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [table](https://v2.grommet.io/table) | Offers table for dynamic data: sorting, multi-select (onSelect, allowSelectAll), pagination/infinite scroll (onMore), grouping (groupBy), icons/buttons in cells, styling options. |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [data-table](https://carbondesignsystem.com/components/data-table/usage/) | Three main variants: Default, with selection (single/multi-row selection + bulk actions), with expansion (expandable detail panels). Optional sorting, filtering/search in a toolbar and pagination . |\n| [Material UI](https://github.com/mui/material-ui) | [table](https://mui.com/material-ui/react-table/) | Table with subcomponents for static display. TablePagination for paging controls. The basic Table has no sticky headers or interactive Features. DataGrid provides sticky header, column grouping, expandable rows, sorting, filtering and selection. |\n| [MongoDB.design](https://github.com/mongodb/design) | [table](https://www.mongodb.design/component/table/live-example) | Static table by default. Hook [useLeafyGreenTable](https://www.npmjs.com/package/@leafygreen-ui/table) integrates TanStack/React-Table for sorting, expansion, selection, sticky headers and large-data loading. |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [table](https://designsystem.porsche.com/v3/components/table/configurator/) | Web Component `<p-table>` with `<p-table-head>`, `<p-table-row>`, etc. Focus on responsiveness and consistency. Supports fixed or percentage column widths. Advanced table can have inline icons/buttons and checkbox selection. Sorting indicator rendered but data reordering done by developer. |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [table](https://lyne-storybook.app.sbb.ch/?path=/docs/styles-table--docs) | No custom table markup, they use native table, but [wrap it for enhancements](https://lyne-storybook.app.sbb.ch/?path=/docs/elements-sbb-table-sbb-table-wrapper--docs): horizontal scroll with buttons, optional sticky header, fixed height and focusable attribute to jump to scroll container. |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [table](https://polaris.shopify.com/components/tables) | DataTable with column definitions with type (text/numeric), right-align numeric. Sortable columns (header buttons manage sort state), footer row for totals. Sticky header and fixed first column. Pagination separate via [Pagination component](https://polaris.shopify.com/components/navigation/pagination). |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [table](https://designmetier-bootstrap.sncf.fr/docs/4.3/content/tables/) | Native table or a wrapper component with scroll-buttons below the table for wide content. Supports fixed headers and responsive swipe on mobile. |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [table](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/table) | Simple table component for static data. Renders native table with responsive container. Interactive features (sorting/filtering) not provided out-of-the-box in initial release. |\n| [Telekom Scale](https://github.com/telekom/scale) | [table](https://telekom.github.io/scale/?path=/docs/components-table--standard) | Simple native table with a wrapper. Supports sorting for columns and striped rows. |\n| [Washington Post Design System](https://build.washingtonpost.com/) | [table (coming soon)](https://build.washingtonpost.com/components/table) / \u274C | -- |\n\n## Conclusion \u{1F3C1}\n\nThe design systems we reviewed tend to follow two approaches based on their technological foundations: framework-oriented systems (e.g. React/Angular) often encapsulate table logic in sophisticated components, whereas technology-agnostic solutions (Web Components or pure HTML/CSS libraries) primarily supply styles and structure and leave the interactive logic to implementers.\n\nAcross the surveyed design systems, there is a kind of pattern for tables:\n\n1. **Native HTML Tables as the Foundation**\n\n Nearly every system relies on the browser\u2019s built-in `<table>` semantics, often wrapped in a lightweight component or CSS utility (e.g. Bootstrap, SBB Lyne, SNCF).\n This ensures maximum accessibility out of the box, since screen readers and keyboard users already understand native table structures.\n\n2. **Progressive Enhancement of Interactivity**\n - **Static by Default**: Some systems stick to purely static tables with CSS-based styling (striped rows, borders) and responsive wrappers for horizontal scrolling. Those have no built-in interactivity (sorting, pagination, etc.).\n - **Developer-Driven Features**: Several systems provide core table markup plus optional wrappers or slots for sorting, sticky headers, and scroll controls, leaving the actual user-driven logic to the implementer.\n - **Built-in Data Tables**: Other systems offer rich, pre-wired data table components with pagination, sorting, row selection, expandable rows, and more. These components manage state, callbacks, and ARIA attributes internally.\n\n3. **Accessibility as a First Principle**\n\n All systems emphasize semantic markup (`<caption>`, `<th scope="\u2026">`, native roles) and appropriate ARIA attributes (`aria-sort`, `aria-expanded`, live regions for announcements).\n\n Many provide built-in helper props or methods to automatically generate accessible labels (e.g. Primer\u2019s `<Table.Title>` or Carbon\u2019s keyboard focus patterns).\n So every system uses the native a11y features of the browser and adds ARIA attributes where necessary.\n\n4. **Responsive and Theming Considerations**\n\n A common requirement is horizontal scrolling on narrow viewports, mostly achieved via wrappers, CSS overflow, or built-in scroll buttons. Systems also offer scoped styling variables or props to adjust row density, header stickiness, and column widths.\n\n## Possible roadmap based on implementation complexity \u{1F4CD}\n\n### \u{1F7E2} V1 - Simple and basic features\n\nVersion 1 delivers a fully functional static table component that renders data in rows and columns using semantic HTML markup, basic styling, lightweight responsive enhancements and optional CSS sticky headers, but excludes any dynamic interactions.\nThis provides an immediately usable, accessible foundation consistent with the initial table offerings of many design systems.\n\n- **Static table rendering**\n\n Display data in rows and columns without any dynamic interaction.\n\n- **Semantic HTML markup**\n\n Use `<table>`, `<thead>`, `<tr>`, `<th>` and `<td>` appropriately.\n\n Header cells must be `<th>` with the correct `scope="col"` or `scope="row"` so that screen readers understand the table structure.\n\n- **Table caption**\n\n Provide a visible `<caption>` or at least an `aria-label` / `aria-labelledby` on the `<table>` element to communicate the table\u2019s title.\n\n- **Responsive layout**\n\n Allow horizontal scrolling on narrow viewports (e.g. via an overflow wrapper or a CSS class).\n\n Ensure the header either scrolls with the body or remains fixed.\n\n- **Basic styling**\n\n Optional visual enhancements that don\u2019t affect interactivity (zebra-striping for rows, condensed row spacing, row hover highlights).\n\n- **Alignment and formatting**\n\n Left-align text, right-align numbers (as recommended by many design systems).\n\n Consistent formatting (e.g. date formats) should also be part of the basic features.\n\n- **Focus indicators**\n\n When a cell is focusable, it should show a visible focus outline (typically handled by the browser).\n\n- **Handle empty table (no data)**\n\n The table should handle the case that no dat is available and show an appropriate message (e.g. "No data available") and use an `aria-live` region to announce the empty state.\n\n### \u{1F535} V2 - Intermediate features\n\nVersion 2 introduces the essential interactive capabilities expected in modern data tables.\nThese enhancements align the component with the intermediate offerings of established design systems, transforming it from a static display into a dynamic data grid for common data exploration tasks.\n\n- **Sortable columns**\n\n Let users sort by any column. Requires header buttons, sorting logic in code, `aria-sort="ascending"` / `"descending"` on the active header and [a description within caption, that any header is sortable](https://www.w3.org/WAI/ARIA/apg/patterns/table/examples/sortable-table/).\n\n- **Pagination**\n\n For large data sets, show pages with \u201CPrevious\u201D / \u201CNext\u201D or page numbers. Requires page-state management and a separate pagination UI.\n\n Buttons need `aria-label` (e.g. \u201CNext page\u201D).\n\n- **Filtering / Search**\n\n Provide filter inputs or a search box to hide rows client-side.\n\n Filter field needs a label and (optionally) a live region announcing \u201C10 of 50 rows shown.\u201D\n\n- **Sticky header**\n\n Keep the header row visible on scroll using CSS (`position: sticky; top: 0;`).\n\n- **Row selection**\n\n Allow selecting rows via checkboxes or click for bulk actions.\n\n Needs a checkbox column and an optional \u201CSelect All\u201D header checkbox.\n `aria-checked`for a11y (including mixed state) and support for spacebar toggling.\n\n- **Inline row actions**\n\n Buttons in each row (e.g. \u201CEdit\u201D, \u201CDelete\u201D).\n\n Each action button should include row context in its `aria-label` (e.g. `aria-label="Edit order #12345"`).\n\n- **Grouped column headers**\n\n Combine multiple columns under a shared header using `<th colspan="\u2026">`.\n\n May require correct DOM hierarchy. Screen readers handle proper HTML automatically.\n\n- **Advanced responsive behavior**\n\n On mobile, transform rows into card-like stacks (label-value blocks) instead of scrolling.\n\n- **Loading States**\n\n Show a loading indicator or skeleton rows when data is being fetched asynchronously, ensuring users receive visual feedback during pagination or lazy-loading. Needs a label and (optionally) a live region announcing the loading state.\n\n- **Customization APIs**\n\n Expose hooks and props that let developers tailor cell rendering, styling, and event handling without patching the component\u2019s internals:\n\n **Cell Templates**: Allow custom render functions or slots so any cell can display content (e.g. badges, links, nested components).\n\n **Event Callbacks**: Provide clear callbacks for all user actions (onSort, onFilter, onSelect, onPageChange, etc.), enabling seamless integration with application logic.\n\n **Styling/Theming**: Offer density, color, and layout overrides (e.g. a compact mode prop or CSS variables) to align with different brand themes.\n\n- **Aggregations / Footer Rows**\n\n Support an optional footer row for totals, averages, or summary data, enabling built-in aggregation without extra markup.\n\n### \u{1F534} V3 - Advanced features\n\nVersion 3 adds advanced, power-user functionality. These sophisticated features elevate the component into a comprehensive data grid suitable for complex, enterprise-grade applications.\n\n- **Inline cell editing**\n\n Let users edit cells directly (like Excel). Requires `contenteditable` or input fields, focus management, validation, and WAI-ARIA grid patterns (`role="grid"` with focused cells).\n\n- **Complex keyboard navigation (grid pattern)**\n\n Arrow-key movement between cells in a fully interactive grid. Needs `role="grid"`, `role="row"` / `role="gridcell"`, and extensive JavaScript for key handling.\n\n (Implementation only if really necessary; native `<table>` support is usually sufficient.)\n\n- **Hierarchical tables (treegrid)**\n\n Parent\u2013child rows that expand/collapse. Use `aria-expanded` on toggles and optionally `role="rowgroup"` for nested groups.\n\n- **Column settings (Show/Hide/Reorder)**\n\n Let users toggle column visibility and reorder via drag-and-drop. Requires a UI for column checkboxes, drag handles, and state management.\n\n Drag & drop must be keyboard-accessible (ARIA Drag-and-Drop or alternative UI).\n\n- **Virtual scrolling for large datasets**\n\n Render only visible rows and load more on scroll. Transparent to users but technically intricate.\n\n Must ensure screen readers can still access all content.\n\n- **Column Resizing**\n\n Enable users to adjust column widths via drag handles, with keyboard-accessible alternatives, for a fully flexible grid layout.\n\n- **Row Drag-and-Drop**\n\n Allow reordering of rows through drag-and-drop (and keyboard equivalents), exposing ARIA drag-and-drop attributes.\n\n- **Export / Import functionality**\n\n Buttons to export the table as CSV/Excel or import data.\n', "docs/research/tabs.md": '# DEV Research tabs\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [tabs](https://atlassian.design/components/tabs/examples) | 3 div-tags with aria- and role-attributes |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [navs](https://getbootstrap.com/docs/4.3/components/navs/#tabs) | nav-component with .nav-tabs class, `ul role=tablist`, `li`, `a role=tab`, `div role=tabpanel` |\n| [GitHub Primer](https://github.com/primer/css) | [tab nav](https://primer.style/components/tab-nav) / [tab panels](https://primer.style/design/components/) | tab-nav: set of links to switch between views, tab-panels: list of buttons to switch between views |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [tabs](https://design.gitlab.com/components/tabs) | `ul role=tablist`, `li`, `a role=tab`, `div role=tabpanel` -> tabgroup + tab&label + tab panel |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [tabs](https://v2.grommet.io/tabs) | `div role=tablist`, `button role=tab`,`div role=tabpanel` -> Components:`<Tabs>` + `<Tab>` + `<any>` (with aria and role attributes) |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [tabs](https://carbondesignsystem.com/components/tabs/usage) | `div role=tablist`, `button role=tab`, `div role=tabpanel` -> `<TabList>` & `<Tab>` + `<TabPanels>` & `<TabPanel>` (with aria attributes) |\n| [Material UI](https://mui.com/material-ui/react-tabs/) | [tabs](https://mui.com/material-ui/react-tabs/) | `div role=tablist`, `button role=tab`, `div role=tabpanel` -> `<TabList>` & `<Tab>` + `<TabPanel>` (with aria attributes) |\n| [MongoDB.design](https://github.com/mongodb/design) | [tabs](https://www.mongodb.design/component/tabs/example/) | `div role=tablist`, `button role=tab`, `div role=tabpanel` |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [tabs](https://designsystem.porsche.com/v3/components/tabs/examples) | `div role=tablist`, `button role=tab`, `p role=tabpanel` |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [tab-group & tab-tile](https://lyne-storybook.app.sbb.ch/?path=/docs/components-sbb-tab-sbb-tab-group--docs) | tabgroup + tabtitle + any =>`div role=tablist`, `div role=tab`, `article role="tabpanel"` |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [tabs](https://polaris.shopify.com/components/navigation/tabs) | 1 component (`<Tabs>`)-> `<ul role=tablist>`,`<li><button role=tab>`,`<div role=tabpanel>`, `fittet` prop for 2-3 tabs, `action` prop to add new tab |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [navs/tabs](https://designmetier-bootstrap.sncf.fr/docs/4.3/layout/navs/#tabs) | `nav role="navigation"`,`<ul>`,`<li>` |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [tabs](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/tabs) | `div`, `button role=tab`, no panels |\n| [Telekom Scale](https://github.com/telekom/scale) | [tab-navigation](https://telekom.github.io/scale/?path=/docs/components-tab-navigation--text-icon) | `div role=tablist`, `span role=tab`, `div role="tabpanel"` |\n| [Washington Post Design System](https://build.washingtonpost.com/) | [tabs](https://build.washingtonpost.com/components/tabs) | `div role=tablist`, `button role=tab`, `div`, alignment, disabled, overflow, !activationMode! |\n| [W3C](https://www.w3.org/WAI/ARIA/apg/patterns/) | [tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/) | Tabs -> Tablist = set of tab-elements (serves as label for tabpanel) -> activation displays content of tabpanel; aria and role attributes accurately described |\n\n## Conclusion\n\n- we can use tab component of [db-ui/elements](https://github.com/db-ui/elements/blob/main/packages/db-ui-elements-stencil/src/components/db-tab/db-tab.tsx)\n- replace `<section>` by `<article>`\n- we use [`role=tablist`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tablist_role), [`role=tab`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role), [`role=tabpanel`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)\n- we use [`aria-controls`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-controls), [`aria-selected`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-selected), [`aria-labelledby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby)\n- We could still explore to use hyperlinks `a href="#tab01"` with anchors and using `:target` to display each tab\n- We could still explore to use `details` and `summary` elements especially due to their `name`-attributes enhancement lately\n\nFindings:\n\n- Some design systems are using `activation-mode=auto/manual` - is this a valid use-case for design? Default should be `auto` select which first tab selected\n- Prop `label` should be a slot to pass in e.g. a `<span>` and a `<DBBadge>`\n- Shall we provide a `badgeNumber` as a default property?\n- `fitted` property should be `width=auto/full`\n', "docs/research/text.md": "# DEV Research text\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [text](https://atlassian.design/components/primitives/text/examples) | `as` property with `span (default)`, `p`, `strong`, `em` |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [text](https://getbootstrap.com/docs/4.3/utilities/text/) | only classes |\n| [GitHub Primer](https://github.com/primer/css) | [text](https://primer.style/product/components/text/) | `as` property with `span (default)` + all React.Elements, `whiteSpace` property |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [typography](https://design.gitlab.com/product-foundations/type-fundamentals) | no direct component |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [text](https://v2.grommet.io/text) | `tag` with`div (default)`,`skeleton` property,`truncate` property |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [typography](https://carbondesignsystem.com/elements/typography/overview/) | no direct component |\n| [Material UI](https://github.com/mui/material-ui) | \u274C | -- |\n| [MongoDB.design](https://github.com/mongodb/design) | [typography](https://www.mongodb.design/component/typography/live-example) | no direct component |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | [typography](https://designsystem.porsche.com/v3/tailwindcss/typography/examples/#text) | only classes |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [typography](https://lyne-storybook.app.sbb.ch/?path=/docs/styles-typography--docs) | only classes |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [text](https://polaris-react.shopify.com/components/typography/text) | `<Text variant=\"bodyLg\" as=\"p\">` variant + `as 'dt', 'dd' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' , 'p' , 'span' , 'strong' , 'legend'`, `visuallyHidden` property |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [text](https://designmetier-bootstrap.sncf.fr/docs/4.3/utilities/text/) | only classes |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [typography](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/fundamentals/typography) | no direct component |\n| [Telekom Scale](https://github.com/telekom/scale) | [typography](https://telekom.github.io/scale/?path=/docs/guidelines-typography--page) | no direct component |\n| [Washington Post Design System](https://build.washingtonpost.com/) | [typography](https://build.washingtonpost.com/foundations/typography/) | no direct component |\n\n## Conclusion\n\n- We should use `as` property with a default `span` or `p`\n- We need to check which HTML tags makes sense to control with the `<Text>` component:\n - [del](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/del)??\n - [dt](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dt)??\n - [dd](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dd)??\n - [ins](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/ins)??\n - [legend](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/legend)??\n - etc.\n- `visuallyHidden` as dev property might be a good idea\n- shall we use [`code`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/code) as well??\n- [`text-wrap`](https://developer.chrome.com/docs/css-ui/css-text-wrap-balance)-CSS-property (especially with the value `\"pretty\"`) would be a relevant aspect to think about\n", "docs/research/tooltip.md": '# DEV Research tooltip\n\n## Overview\n\n| Design System | Component | Comment |\n| --------------------------------------------------------------------------------------- | :-----------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------- |\n| [Atlassian Design System](https://bitbucket.org/atlassian/atlaskit/src/master/) | [tooltip](https://atlassian.design/components/tooltip/examples) | wrapping tag, onHover with aria-describedby, uses internal popper for placement |\n| [Bootstrap](https://github.com/twbs/bootstrap) | [tooltip](https://getbootstrap.com/docs/4.3/components/tooltips/) | uses [Popper.js](https://popper.js.org/), `data-toggle="tooltip"` & `data-placement="top"` |\n| [GitHub Primer](https://github.com/primer/css) | [tooltip](https://primer.style/design/components/tooltip) | wrapping tag, <https://primer.style/design/guides/accessibility/tooltip-alternatives> |\n| [GitLab Pajamas](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com) | [tooltip](https://design.gitlab.com/components/tooltip) | wrapping tag, onHover with aria-describedby + title |\n| [HP Enterprise Grommet](https://github.com/grommet/grommet) | [tip](https://v2.grommet.io/tip) | wrapping tag, onHover add to dom |\n| [IBM Carbon](https://github.com/carbon-design-system/carbon) | [tooltip](https://carbondesignsystem.com/components/tooltip/usage/) | wrapper tag, onHover enables span with role=tooltip |\n| [Material UI](https://github.com/mui/material-ui) | [tooltip](https://mui.com/material-ui/react-tooltip/) | wrapping tag, onHover add to dom |\n| [MongoDB.design](https://github.com/mongodb/design) | [tooltip](https://www.mongodb.design/component/tooltip/example/) | wrapping tag, onHover add to dom |\n| [Porsche Design System](https://github.com/porsche-design-system/porsche-design-system) | \u274C | |\n| [SBB Lyne](https://github.com/lyne-design-system/lyne-components) | [tooltip](https://lyne-storybook.app.sbb.ch/?path=/docs/components-sbb-tooltip-sbb-tooltip--docs) | own component + wrapping trigger |\n| [Shopify Polaris](https://github.com/Shopify/polaris) | [tooltip](https://polaris.shopify.com/components/overlays/tooltip) | wrapping tag + `::after` |\n| [SNCF Design System](https://gitlab.com/SNCF/wcs) | [tooltips](https://designmetier-bootstrap.sncf.fr/docs/4.3/components/tooltips/) | `data-toggle="tooltip"` + `data-placement="top"` + `title="Tooltip on top"`, onHover add to dom |\n| [Telefonica Mistica](https://github.com/Telefonica/mistica-web) | [tooltip](https://brandfactory.telefonica.com/d/iSp7b1DkYygv/n-a#/components/tooltip) | wrapping tag + `aria-expand` |\n| [Telekom Scale](https://github.com/telekom/scale) | [tooltip](https://telekom.github.io/scale/?path=/docs/components-tooltip--standard) | wrapping tag + `open` |\n| [Washington Post Design System](https://build.washingtonpost.com/) | [tooltip](https://build.washingtonpost.com/components/tooltip) | wrapping tag + dom |\n\n## Conclusion\n\nThere are two ways to use a tooltip:\n\n1. As wrapping tag `<tooltip content="xyz"><button>Test</button></tooltip>`\n2. As property `<button tooltip/title="xyz">Test</button>`\n\n---\n\nWe should use a wrapping tag similar to IBM and a [title fallback](https://stackoverflow.com/questions/2011142/how-to-change-the-style-of-the-title-attribute-inside-an-anchor-tag).\n\nAdvantages wrapping tag:\n\n- We can use `::before` or `::after` for the arrow\n- We can use `string` and `slot` for the content\n- We have a position for the wrapping div which can be used by JS\n\nDisadvantages wrapping tag:\n\n- Not using default `title`\n- Could be hard to use default `:hover` or `:focus`\n\nFindings:\n\n- By providing and `open` state we could let the user handle if the tooltip should be shown\n- We could use `behaviour` to enable different states like `hover` or `clicked` etc.\n\n---\n\n### MDN\n\n<https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tooltip_role>\n', "docs/research-other-design-systems.md": `# Other design systems
22539
+
22540
+ We'd like to maintain a list of other design systems that might be interesting for research and inspiration, and even include meta information especially regarding technical aspects.
22541
+
22542
+ - [Telekom Scale](https://github.com/telekom/scale), Tech Stack:
22543
+ - Web Components / StencilJS
22544
+ - Storybook
22545
+ - [SBB / Lyne Components](https://github.com/lyne-design-system/lyne-components), Tech Stack:
22546
+ - Web Components / ~StencilJS~ Lit
22547
+ - [Storybook](https://lyne-storybook.app.sbb.ch/)
22548
+ - [SBB / Websites](https://digital.sbb.ch/de/websites) & [SBB / Webapps](https://digital.sbb.ch/de/webapps)
22549
+ - [SBB Angular](https://angular.app.sbb.ch/angular/introduction/getting-started)
22550
+ - [SBB Angular GitHub](https://github.com/sbb-design-systems/sbb-angular)
22551
+ - [SNCF Design System](https://designmetier-bootstrap.sncf.fr/), Tech Stack (among others):
22552
+ - [Web Components / StencilJS](https://gitlab.com/SNCF/wcs)
22553
+ - Storybook
22554
+ - [IBM / Carbon Design System](https://github.com/carbon-design-system/carbon)
22555
+ - ["React first, with official support for Web Components"](https://carbondesignsystem.com/developing/frameworks/other-frameworks)
22556
+ - Storybook
22557
+ - [Material Web](https://github.com/material-components/material-web)
22558
+ - Web Components
22559
+ - [NS.nl / Platform](https://www.ns.nl/platform/components/index.html)
22560
+ - [Liquid Oxygen, UI component library for the Liquid Design System of Merck KGaA](https://liquid.merck.design/liquid/)
22561
+ - Web Components / StencilJS
22562
+ - [Porsche Design System](https://designsystem.porsche.com/v3/)
22563
+ - Web Components / StencilJS
22564
+ - [Barmer Puls Design System](https://barmer-puls.entw.bconnect.barmer.de/) <!-- codespell:ignore -->
22565
+ - React Native
22566
+ - [Storybook](https://barmer-puls-react.entw.bconnect.barmer.de/?path=/story/surfaces-accordion--base)
22567
+ - [SAP UI5 Web Components](https://sap.github.io/ui5-webcomponents/)
22568
+ - [Web Components](https://github.com/SAP/ui5-webcomponents)
22569
+ - [Audi Design System](https://www.audi.com/ci/en/guides/user-interface/components/buttons.html)
22570
+ - React
22571
+ - [DHL Design System](https://www.dpdhl-brands.com/en/dhl/buttons)
22572
+ - React
22573
+ - [Netherlands government](https://nldesignsystem.nl/), Tech Stack (among others):
22574
+ - Web Components / StencilJS
22575
+ - Storybook
22576
+ - [wien.gv.at](https://handbuch.wien.gv.at/pattern-library/patterns/)
22577
+ - HTML & CSS first
22578
+ - JavaScript only as an addition, mainly because of that the target are content pages even only
22579
+ - Web Components (upcoming)
22580
+ - ["Informationstechnikzentrum Bund" Germany / KoliBri steht f\xFCr "Komponentenbibliothek f\xFCr die Barrierefreiheit"](https://public-ui.github.io/) <!-- codespell:ignore -->
22581
+ - Web Components / StencilJS
22582
+ - [Washington Post Design System (WPDS)](https://build.washingtonpost.com/)
22583
+ - React
22584
+ - [GOV.UK Design System](https://design-system.service.gov.uk/)
22585
+ - [Paste](https://paste.twilio.design/)
22586
+ - [Swiss Post](https://github.com/swisspost/design-system):
22587
+ - Web Components / StencilJS
22588
+ - [Solid Design](https://github.com/solid-design-system/solid):
22589
+ - Web Components
22590
+
22591
+ ## Design System "registries" / overviews
22592
+
22593
+ - <https://adele.uxpin.com/>
22594
+ - <https://storybook.js.org/showcase>
22595
+ - <https://component.gallery/>
22596
+
22597
+ ## Further inspirational websites
22598
+
22599
+ - <https://www.w3.org/WAI/ARIA/apg/patterns/>
22600
+ - <https://inclusive-components.design/#components>
22601
+ `, "docs/stylelint-scss-config.md": "# Differences in between `stylelint-config-standard-scss` and `stylelint-config-recommended-scss`\n\n## Short version\n\n- `stylelint-config-recommended-scss`\n - Minimal, \u201Cavoid bugs\u201D preset for SCSS.\n - Extends the core recommended rules and the SCSS plugin\u2019s recommended rules.\n - Turns off core rules that conflict with SCSS syntax.\n - Little to no stylistic/opinionated formatting. Fewer warnings; great if you use Prettier.\n\n- `stylelint-config-standard-scss`\n - Superset of recommended-scss with opinions.\n - Adds many formatting/convention rules (mostly via `stylelint-stylistic`) for quotes, spacing, commas, hex case/length, newline placement, etc.\n - Still disables core rules that conflict with SCSS, but enforces a consistent style and will surface more issues (mostly auto-fixable).\n\n## Practical guidance\n\n- Use recommended-scss if you want just correctness checks for SCSS and let Prettier handle formatting.\n- Use standard-scss if you want Stylelint to also enforce style conventions across SCSS.\n- Either SCSS preset avoids CSS\u2011Nesting\u2011only checks on .scss files (the \u201Cmissing scoping root\u201D issue appears when using non\u2011SCSS presets like `stylelint-config-standard` on SCSS).\n" } };
22602
+
21646
22603
  // ../mcp-server/src/utils/manifest.ts
21647
- import { existsSync as existsSync2 } from "node:fs";
21648
- import { readFile } from "node:fs/promises";
21649
- import { join as join2, resolve as resolve2 } from "node:path";
21650
- var SERVER_DIR2 = resolve2(import.meta.dirname, "..");
21651
22604
  var _manifest = null;
21652
- function resetManifestCache() {
21653
- _manifest = null;
22605
+ function resetManifestCache(override) {
22606
+ _manifest = override ?? null;
21654
22607
  }
21655
22608
  async function getManifest() {
21656
22609
  if (_manifest) return _manifest;
21657
- const manifestPath = join2(SERVER_DIR2, "manifest.json");
21658
- if (!existsSync2(manifestPath)) {
21659
- throw new Error(`manifest.json not found at ${manifestPath}`);
21660
- }
21661
- try {
21662
- _manifest = JSON.parse(await readFile(manifestPath, "utf-8"));
21663
- } catch {
21664
- throw new Error("Failed to parse manifest.json \u2014 file may be corrupt or incomplete.");
21665
- }
22610
+ _manifest = manifest_default;
21666
22611
  return _manifest;
21667
22612
  }
21668
22613
 
@@ -21679,9 +22624,9 @@ var COMPONENT_NOT_FOUND_MSG = (name) => `Error: Component '${name}' is not avail
21679
22624
  var TOOL_TIMEOUT_MS = 1e4;
21680
22625
  async function withTimeout(operation, timeoutMessage) {
21681
22626
  let timer;
21682
- const timeoutPromise = new Promise((resolve3) => {
22627
+ const timeoutPromise = new Promise((resolve2) => {
21683
22628
  timer = setTimeout(() => {
21684
- resolve3({ content: [{ type: "text", text: timeoutMessage }], isError: true });
22629
+ resolve2({ content: [{ type: "text", text: timeoutMessage }], isError: true });
21685
22630
  }, TOOL_TIMEOUT_MS);
21686
22631
  });
21687
22632
  const result = await Promise.race([operation, timeoutPromise]);
@@ -21700,7 +22645,7 @@ function resolveComponentPath(baseDir, componentName) {
21700
22645
  } catch {
21701
22646
  return err(`Error: Invalid component name '${componentName}'.`);
21702
22647
  }
21703
- if (!existsSync3(safePath)) {
22648
+ if (!existsSync2(safePath)) {
21704
22649
  return err(COMPONENT_NOT_FOUND_MSG(componentName));
21705
22650
  }
21706
22651
  return safePath;
@@ -21740,18 +22685,18 @@ async function handleGetComponentDetails({
21740
22685
  if (IS_MONOREPO) {
21741
22686
  const pathOrError = resolveComponentPath(COMPONENTS_DIR, componentName);
21742
22687
  if (typeof pathOrError !== "string") return pathOrError;
21743
- const showcaseFile = join3(
22688
+ const showcaseFile = join2(
21744
22689
  pathOrError,
21745
22690
  "showcase",
21746
22691
  `${componentName}.showcase.lite.tsx`
21747
22692
  );
21748
- if (!existsSync3(showcaseFile)) {
22693
+ if (!existsSync2(showcaseFile)) {
21749
22694
  return err(
21750
22695
  `Error: File for component '${componentName}' not found.`
21751
22696
  );
21752
22697
  }
21753
22698
  const source = truncate(
21754
- await readFile2(showcaseFile, "utf-8"),
22699
+ await readFile(showcaseFile, "utf-8"),
21755
22700
  MAX_FILE_CONTENT
21756
22701
  );
21757
22702
  const examples = [...source.matchAll(/exampleName="([^"]+)"/g)].map(
@@ -21784,8 +22729,8 @@ async function handleGetComponentProps({
21784
22729
  if (IS_MONOREPO) {
21785
22730
  const pathOrError = resolveComponentPath(COMPONENTS_DIR, componentName);
21786
22731
  if (typeof pathOrError !== "string") return pathOrError;
21787
- const modelFile = join3(pathOrError, "model.ts");
21788
- if (!existsSync3(modelFile)) {
22732
+ const modelFile = join2(pathOrError, "model.ts");
22733
+ if (!existsSync2(modelFile)) {
21789
22734
  return err(
21790
22735
  `Error: Props file (model.ts) for component '${componentName}' not found.`
21791
22736
  );
@@ -21795,7 +22740,7 @@ async function handleGetComponentProps({
21795
22740
  {
21796
22741
  type: "text",
21797
22742
  text: truncate(
21798
- await readFile2(modelFile, "utf-8"),
22743
+ await readFile(modelFile, "utf-8"),
21799
22744
  MAX_FILE_CONTENT
21800
22745
  )
21801
22746
  }
@@ -21847,19 +22792,19 @@ async function handleGetExampleCode({
21847
22792
  const ext = FRAMEWORK_EXT[framework];
21848
22793
  if (IS_MONOREPO) {
21849
22794
  if (framework === "html") {
21850
- const htmlFile = join3(
22795
+ const htmlFile = join2(
21851
22796
  COMPONENTS_DIR,
21852
22797
  componentName,
21853
22798
  "index.html"
21854
22799
  );
21855
- if (!existsSync3(htmlFile))
22800
+ if (!existsSync2(htmlFile))
21856
22801
  return err(COMPONENT_NOT_FOUND_MSG(componentName));
21857
22802
  return {
21858
22803
  content: [
21859
22804
  {
21860
22805
  type: "text",
21861
22806
  text: truncate(
21862
- await readFile2(htmlFile, "utf-8"),
22807
+ await readFile(htmlFile, "utf-8"),
21863
22808
  MAX_FILE_CONTENT
21864
22809
  )
21865
22810
  }
@@ -21868,20 +22813,20 @@ async function handleGetExampleCode({
21868
22813
  }
21869
22814
  const outputSubDir = FRAMEWORK_OUTPUT_DIR[framework] ?? framework;
21870
22815
  const pathOrError = resolveComponentPath(
21871
- join3(OUTPUT_DIR, outputSubDir, "src/components"),
22816
+ join2(OUTPUT_DIR, outputSubDir, "src/components"),
21872
22817
  componentName
21873
22818
  );
21874
22819
  if (typeof pathOrError !== "string") return pathOrError;
21875
- const examplesDir = join3(pathOrError, "examples");
21876
- let resolvedPath = join3(
22820
+ const examplesDir = join2(pathOrError, "examples");
22821
+ let resolvedPath = join2(
21877
22822
  examplesDir,
21878
22823
  `${kebab}.example.${ext}`
21879
22824
  );
21880
- if (!existsSync3(resolvedPath)) {
21881
- const allEntries = existsSync3(examplesDir) ? await readdir(examplesDir) : [];
22825
+ if (!existsSync2(resolvedPath)) {
22826
+ const allEntries = existsSync2(examplesDir) ? await readdir(examplesDir) : [];
21882
22827
  const match = fuzzyMatchExample(allEntries, kebab, ext);
21883
22828
  if (match) {
21884
- resolvedPath = join3(examplesDir, match);
22829
+ resolvedPath = join2(examplesDir, match);
21885
22830
  } else {
21886
22831
  return err(
21887
22832
  `Error: Example '${exampleName}' for component '${componentName}' not found. Use 'get_component_details' to see available examples.`
@@ -21893,7 +22838,7 @@ async function handleGetExampleCode({
21893
22838
  {
21894
22839
  type: "text",
21895
22840
  text: truncate(
21896
- await readFile2(resolvedPath, "utf-8"),
22841
+ await readFile(resolvedPath, "utf-8"),
21897
22842
  MAX_FILE_CONTENT
21898
22843
  )
21899
22844
  }
@@ -21946,12 +22891,12 @@ async function handleGetExampleCode({
21946
22891
  }
21947
22892
 
21948
22893
  // ../mcp-server/src/tools/tokens.ts
21949
- import { existsSync as existsSync4 } from "node:fs";
21950
- import { readFile as readFile3 } from "node:fs/promises";
22894
+ import { existsSync as existsSync3 } from "node:fs";
22895
+ import { readFile as readFile2 } from "node:fs/promises";
21951
22896
  async function handleListDesignTokenCategories() {
21952
22897
  if (IS_MONOREPO) {
21953
22898
  const categories = Object.keys(TOKEN_FILES).filter(
21954
- (key) => existsSync4(TOKEN_FILES[key])
22899
+ (key) => existsSync3(TOKEN_FILES[key])
21955
22900
  );
21956
22901
  return {
21957
22902
  content: [
@@ -22011,7 +22956,7 @@ async function handleGetDesignTokens({
22011
22956
  isError: true
22012
22957
  };
22013
22958
  }
22014
- if (!existsSync4(filePath)) {
22959
+ if (!existsSync3(filePath)) {
22015
22960
  return {
22016
22961
  content: [
22017
22962
  {
@@ -22022,7 +22967,7 @@ async function handleGetDesignTokens({
22022
22967
  isError: true
22023
22968
  };
22024
22969
  }
22025
- const source = await readFile3(filePath, "utf-8");
22970
+ const source = await readFile2(filePath, "utf-8");
22026
22971
  const lines = source.split("\n").filter((line) => /--db-|^\$db-/.test(line));
22027
22972
  return {
22028
22973
  content: [
@@ -22038,11 +22983,11 @@ async function handleGetDesignTokens({
22038
22983
  }
22039
22984
 
22040
22985
  // ../mcp-server/src/tools/icons.ts
22041
- import { existsSync as existsSync5 } from "node:fs";
22042
- import { readFile as readFile4 } from "node:fs/promises";
22986
+ import { existsSync as existsSync4 } from "node:fs";
22987
+ import { readFile as readFile3 } from "node:fs/promises";
22043
22988
  async function handleListIcons() {
22044
- if (IS_MONOREPO && existsSync5(ALL_ICONS_FILE)) {
22045
- const source = await readFile4(ALL_ICONS_FILE, "utf-8");
22989
+ if (IS_MONOREPO && existsSync4(ALL_ICONS_FILE)) {
22990
+ const source = await readFile3(ALL_ICONS_FILE, "utf-8");
22046
22991
  const icons = [...source.matchAll(/'([^']+)'/g)].map((m) => m[1]);
22047
22992
  return {
22048
22993
  content: [
@@ -22071,9 +23016,9 @@ async function handleListIcons() {
22071
23016
  }
22072
23017
 
22073
23018
  // ../mcp-server/src/tools/docs.ts
22074
- import { existsSync as existsSync6 } from "node:fs";
22075
- import { readFile as readFile5, readdir as readdir2 } from "node:fs/promises";
22076
- import { join as join4 } from "node:path";
23019
+ import { existsSync as existsSync5 } from "node:fs";
23020
+ import { readFile as readFile4, readdir as readdir2 } from "node:fs/promises";
23021
+ import { join as join3 } from "node:path";
22077
23022
  function buildResults(results, query) {
22078
23023
  if (results.length === 0) {
22079
23024
  return {
@@ -22155,15 +23100,15 @@ ${snippet}`);
22155
23100
  isError: true
22156
23101
  };
22157
23102
  }
22158
- const compDocsDir = join4(safeComponentPath, "docs");
22159
- if (existsSync6(compDocsDir)) {
23103
+ const compDocsDir = join3(safeComponentPath, "docs");
23104
+ if (existsSync5(compDocsDir)) {
22160
23105
  const files = await readdir2(compDocsDir);
22161
23106
  for (const file of files) {
22162
23107
  if (!file.endsWith(".md")) continue;
22163
23108
  if (docType && !file.toLowerCase().includes(docType.toLowerCase()))
22164
23109
  continue;
22165
- const content = await readFile5(
22166
- join4(compDocsDir, file),
23110
+ const content = await readFile4(
23111
+ join3(compDocsDir, file),
22167
23112
  "utf-8"
22168
23113
  );
22169
23114
  const isMatch = searchTerms.length === 0 || searchTerms.every(
@@ -22181,18 +23126,18 @@ ${content}`
22181
23126
  );
22182
23127
  }
22183
23128
  } else {
22184
- if (existsSync6(DOCS_DIR)) {
23129
+ if (existsSync5(DOCS_DIR)) {
22185
23130
  const searchDir = async (currentDir, depth = 5) => {
22186
23131
  if (depth === 0) return;
22187
23132
  const entries = await readdir2(currentDir, {
22188
23133
  withFileTypes: true
22189
23134
  });
22190
23135
  for (const entry of entries) {
22191
- const fullPath = join4(currentDir, entry.name);
23136
+ const fullPath = join3(currentDir, entry.name);
22192
23137
  if (entry.isDirectory()) {
22193
23138
  await searchDir(fullPath, depth - 1);
22194
23139
  } else if (entry.name.endsWith(".md")) {
22195
- const content = await readFile5(
23140
+ const content = await readFile4(
22196
23141
  fullPath,
22197
23142
  "utf-8"
22198
23143
  );